본문 바로가기
앱개발/Flutter

Dismissible 위젯으로 스와이프 삭제 기능 구현하는 방법

by 김무스비 2024. 10. 29.
728x90
반응형

Flutter 앱 개발에서 흔히 필요한 기능 중 하나는 리스트 항목을 삭제하는 기능입니다. 모바일 앱에서는 일반적으로 사용자가 아이템을 스와이프하여 삭제하거나 특정 액션을 트리거할 수 있도록 만드는 경우가 많죠. 이러한 기능을 Flutter에서 쉽게 구현할 수 있는 것이 바로 Dismissible 위젯입니다. Dismissible 위젯은 리스트 항목을 스와이프로 삭제할 수 있는 기능을 구현할 때 유용하며, ListView와 함께 사용할 때 특히 효과적입니다.

이 글에서는 Dismissible 위젯의 동작 방식, 구현 방법, 실제 사용 예제와 함께, 사용자에게 친숙한 경험을 제공하기 위한 팁까지 다룹니다. Flutter에서 스와이프를 이용한 삭제 기능을 구현하고 싶다면, Dismissible 위젯을 잘 이해하고 활용하는 것이 중요합니다.

swipe image


1. Dismissible 위젯이란?

Dismissible 위젯은 리스트의 아이템을 스와이프하여 삭제할 수 있는 기능을 제공하는 Flutter의 UI 위젯입니다. 사용자가 특정 아이템을 오른쪽이나 왼쪽으로 스와이프하면, 지정된 동작이 실행되고, 아이템이 리스트에서 사라지게 됩니다. 이를 통해 앱 내에서 삭제 기능이나 기타 액션을 간편하게 구현할 수 있으며, 직관적인 인터페이스를 제공합니다.

2. Dismissible 위젯의 주요 속성

Dismissible 위젯은 간단한 구조로 되어 있지만, 다양한 속성을 활용하여 기능을 확장할 수 있습니다.

  • key: Dismissible 위젯은 반드시 고유한 Key가 필요합니다. 이 Key는 각 아이템을 고유하게 식별하는데 사용됩니다.
  • child: Dismissible 위젯 내부에 표시할 컨텐츠를 지정합니다. 보통은 ListTile이나 Card 같은 위젯이 들어가며, 이 child는 스와이프 대상이 됩니다.
  • background: 스와이프하는 동안 보이는 백그라운드 영역을 지정합니다. 스와이프 방향에 따라 다양한 백그라운드를 설정할 수 있어 사용자에게 시각적인 피드백을 줄 수 있습니다.
  • secondaryBackground: 스와이프 반대 방향으로 이동할 때 나타나는 백그라운드입니다. 이 속성을 통해 양방향에서 다른 피드백을 제공할 수 있습니다.
  • onDismissed: 아이템이 스와이프되어 화면에서 완전히 사라질 때 실행되는 콜백 함수입니다. 보통 이곳에서 리스트에서 아이템을 삭제하거나 상태를 업데이트하는 로직을 구현합니다.

3. Dismissible 위젯 기본 사용법

Flutter에서 Dismissible 위젯을 사용하여 리스트 항목을 쉽게 삭제할 수 있습니다. 기본적인 사용 예제를 통해 Dismissible 위젯을 어떻게 구성할 수 있는지 살펴보겠습니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Dismissible 예제"),
        ),
        body: DismissibleExample(),
      ),
    );
  }
}

class DismissibleExample extends StatefulWidget {
  @override
  _DismissibleExampleState createState() => _DismissibleExampleState();
}

class _DismissibleExampleState extends State<DismissibleExample> {
  final List<String> items = List<String>.generate(10, (i) => "Item ${i + 1}");

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: items.length,
      itemBuilder: (context, index) {
        return Dismissible(
          key: Key(items[index]),
          background: Container(
            color: Colors.red,
            alignment: Alignment.centerLeft,
            padding: EdgeInsets.only(left: 20),
            child: Icon(Icons.delete, color: Colors.white),
          ),
          onDismissed: (direction) {
            setState(() {
              items.removeAt(index);
            });

            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text("Item ${index + 1} 삭제됨")),
            );
          },
          child: ListTile(
            title: Text(items[index]),
          ),
        );
      },
    );
  }
}

위 예제에서는 ListView.builder와 Dismissible 위젯을 함께 사용하여 리스트 아이템을 스와이프하여 삭제할 수 있도록 구성했습니다. background 속성으로 스와이프 시 나타날 배경을 지정하고, onDismissed에서 삭제 로직을 구현했습니다.

4. Dismissible 위젯의 확장 기능

기본 기능 외에도 Dismissible 위젯을 활용해 다양한 사용자 경험을 제공할 수 있습니다.

양방향 스와이프

Dismissible 위젯은 양방향 스와이프를 지원합니다. 예를 들어, 오른쪽으로 스와이프하면 삭제, 왼쪽으로 스와이프하면 수정 등의 동작을 지정할 수 있습니다.

secondaryBackground: Container(
  color: Colors.blue,
  alignment: Alignment.centerRight,
  padding: EdgeInsets.only(right: 20),
  child: Icon(Icons.edit, color: Colors.white),
),

스와이프 방향 제한하기

스와이프 방향을 제한하고 싶다면 direction 속성을 설정할 수 있습니다. 예를 들어, DismissDirection.startToEnd로 설정하면 오른쪽 방향 스와이프만 허용됩니다.

5. Dismissible 위젯을 사용할 때 주의할 점

  1. 유니크한 Key 사용
    각 Dismissible 항목에는 반드시 고유한 Key가 필요합니다. ListView.builder와 함께 사용할 때 특히 중요하며, 중복 Key를 사용하면 앱이 충돌할 수 있습니다.
  2. 데이터 관리
    onDismissed 콜백에서 아이템을 삭제할 때, 실제 데이터 소스에서 해당 항목을 삭제하는 것도 잊지 마세요. 데이터가 제대로 업데이트되지 않으면 화면과 데이터 간 불일치가 발생할 수 있습니다.
  3. 애니메이션 효과 최적화
    Dismissible은 기본적으로 애니메이션을 제공하지만, 추가 애니메이션이 필요할 경우 AnimatedList와 같은 위젯과 조합하여 더 부드럽고 자연스러운 삭제 애니메이션을 구현할 수 있습니다.

6. Dismissible 위젯을 활용한 고급 기능 예제

삭제 취소 기능 구현

스와이프 후 아이템을 삭제했지만, 실수로 삭제했을 때 이를 취소할 수 있는 기능을 제공해 사용자 경험을 개선할 수 있습니다.

onDismissed: (direction) {
  String deletedItem = items.removeAt(index);
  
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(
      content: Text("$deletedItem 삭제됨"),
      action: SnackBarAction(
        label: "취소",
        onPressed: () {
          setState(() {
            items.insert(index, deletedItem);
          });
        },
      ),
    ),
  );
},

SnackBarAction을 활용하여 삭제된 아이템을 복원하는 기능을 추가했습니다. 이를 통해 사용자가 실수로 삭제한 항목을 되돌릴 수 있도록 도와줄 수 있습니다.

결론

Dismissible 위젯은 간단하지만 강력한 Flutter 위젯으로, 사용자에게 직관적인 인터페이스를 제공합니다. 스와이프를 통해 삭제나 기타 액션을 손쉽게 구현할 수 있어, 특히 리스트 기반의 앱에서 유용하게 사용할 수 있습니다. Dismissible을 활용해 사용자 경험을 향상시키고, 사용자에게 더욱 친숙한 UI를 제공해 보세요.

728x90
반응형