관리 메뉴

나만을 위한 블로그

[Flutter] 스와이프해서 지우기 구현하는 법(Dismissible) 본문

Flutter

[Flutter] 스와이프해서 지우기 구현하는 법(Dismissible)

참깨빵위에참깨빵 2024. 8. 19. 19:18
728x90
반응형

리스트뷰로 여러 아이템을 표시하는 뷰를 만든 뒤 한쪽으로 스와이프해서 지우는 기능을 만들어야 할 수 있다. 이 때 사용할 수 있는 방법이 리스트뷰 안에서 Dismissible이란 위젯을 사용하는 것이다.

 

https://api.flutter.dev/flutter/widgets/Dismissible-class.html

 

Dismissible class - widgets library - Dart API

A widget that can be dismissed by dragging in the indicated direction. Dragging or flinging this widget in the DismissDirection causes the child to slide out of view. Following the slide animation, if resizeDuration is non-null, the Dismissible widget anim

api.flutter.dev

표시된 방향으로 드래그해서 해제할 수 있는 위젯이다. 이 위젯을 DismissDirection으로 드래그하거나 던지면 자식이 시야 밖으로 미끄러진다. 슬라이드 애니메이션에 이어서 resizeDuration이 null이 아닌 경우, Dismissible은 높이(또는 너비 중 해제 방향에 수직인 것)를 resizeDuration에 대해 0으로 애니메이션한다

 

Dismissible을 사용한 코드는 아래와 같다.

 

import 'package:flutter/material.dart';

void main() {
  runApp(const DismissibleExampleApp());
}

class DismissibleExampleApp extends StatelessWidget {
  const DismissibleExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("Dismissible 예시"),
        ),
        body: const DismissibleExample(),
      ),
    );
  }
}

class DismissibleExample extends StatefulWidget {
  const DismissibleExample({super.key});

  @override
  State<DismissibleExample> createState() => _DismissibleExampleState();
}

class _DismissibleExampleState extends State<DismissibleExample> {

  List<int> items = List<int>.generate(100, (int index) => index);

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemBuilder: (BuildContext context, int index) {
        return Dismissible(
          key: ValueKey<int>(items[index]),
          child: ListTile(
            title: Text("아이템 ${items[index]}"),
          ),
          onDismissed: (DismissDirection direction) {
            setState(() {
              items.removeAt(index);
            });
          },
          background: Container(
            color: Colors.green,
          ),
          secondaryBackground: Container(
            color: Colors.red,
          ),
        );
      },
    );
  }
}

 

이후 아이폰 에뮬레이터에서 실행하면 아래 화면이 표시된다.

 

 

그리고 한 아이템을 한쪽으로 스와이프하면 밀려나면서 배경색이 녹색으로 표시된다.

 

 

완전히 한쪽으로 넘기면 잠시 후 아이템이 제거된다. 그리고 위에선 오른쪽으로 스와이프했을 때 녹색이 표시되지만, secondBackground를 구현한다면 반대 방향으로 스와이프할 때의 색도 설정할 수 있다.

 

 

구현 자체는 그렇게 특이할 게 없지만 Dismissible 안에서 사용한 ValueKey는 무엇인가?

 

https://api.flutter.dev/flutter/foundation/ValueKey-class.html

 

ValueKey class - foundation library - Dart API

A key that uses a value of a particular type to identify itself. A ValueKey is equal to another ValueKey if, and only if, their values are operator==. This class can be subclassed to create value keys that will not be equal to other value keys that happen

api.flutter.dev

특정 타입의 값을 사용해서 자신을 식별하는 키. 값이 연산자 ==인 경우에만 ValueKey<T>는 다른 ValueKey<T>와 동일하다. 이 클래스를 서브클래싱해서 같은 값을 쓰는 다른 value key와 같지 않은 value key를 만들 수 있다. 서브클래스가 private인 경우 다른 소스의 키와 충돌할 수 없는 value key 타입이 생성되므로, 다른 위젯에서 제공된 키와 동일한 범위에서 fallback으로 키를 사용할 경우 유용할  수 있다(키가 다른 위젯에서 제공된 키와 같은 범위에서 fallback으로 쓰이는 경우)

 

https://medium.com/@rishad2002/choosing-the-right-key-exploring-valuekey-objectkey-and-uniquekey-in-flutter-development-40181343ce59

 

Choosing the Right Key: Exploring ValueKey, ObjectKey, and UniqueKey in Flutter Development

In Flutter, keys are crucial elements used to preserve the state and identity of widgets, especially when the widget tree is being rebuilt…

medium.com

특정 값을 기준으로 위젯을 식별한다. 각 항목을 ID 같은 특정 값으로 고유하게 식별해야 하는 목록에서 자주 쓰인다...(중략)...ValueKey는 특정 값을 기반으로 위젯을 고유하게 식별하는 데 도움이 되는 플러터의 key 타입이다. LocalKey 클래스를 상속한 것으로, 동일하지만 다른 값과 연관된 위젯을 구분해야 하는 시나리오에서 특히 유용하다. ValueKey에 쓰이는 값은 문자열, 정수 또는 ==를 구현하고 일관된 해시 코드를 가진 기타 객체 같은 모든 타입이 될 수 있다. 위젯 트리가 다시 빌드될 때 플러터는 이 값을 써서 해당 위젯을 찾고 식별해서 상태를 보존하고 연속성을 보장한다. ValueKey는 특히 아래 시나리오에서 유용하다

1. 리스트와 컬렉션 : 효율적 업데이트, 상태 관리를 위해 각 아이템에 고유 식별자가 필요한 위젯의 리스트 or 컬렉션을 다룰 때 사용
2. 동적 컨텐츠 : 위젯이 동적 생성, 제거, 재정렬될 때 각 위젯을 고유하게 식별할 수 있게 해야 한다
3. 양식 필드(Form Fields) : 위젯 트리에서의 위치와 독립적으로 상태를 유지해야 하는 양식 필드를 관리할 때 사용

 

정리하면 ValueKey는 플러터에서 위젯을 식별할 때 사용하기 위한 고유한 식별자를 만들기 위해 사용하는 Key의 타입 중 하나다. Key는 위젯 트리에서 특정 위젯을 고유하게 식별하고 build()가 재호출될 때, 상태 관리를 더 효율적으로 할 수 있게 도와준다. 위에서 사용한 ValueKey 코드를 확인한다.

 

key: ValueKey<int>(items[index]),

 

int 타입의 ValueKey를 정의했고, items 리스트에 들어있는 각 아이템들의 인덱스를 기반으로 고유한 키를 만든다. 이 키를 Dismissible 위젯에 넘기면 Dismissible은 하드코딩으로 생성된 100개의 아이템들을 모두 고유하게 식별할 수 있게 되고, 아이템을 제거할 때 발생할 수 있는 상태 관련 사이드 이펙트를 방지할 수 있다.

반응형
Comments