Dismissible Widget

이원석·2023년 12월 6일
0

Flutter

목록 보기
36/46

Dismissible Widget

Dismissible은 List에서 특정 아이템을 좌, 우로 움직였을 때, 특정 action을 취하고 아이템이 사라지도록 하는 widget이다.

Listview의 item을 dismissible로 감싸준다.

속성

  • background
    child 아래에 있어서 child widget을 드래그 해야 보이는 widget
    secondaryBackground도 지정되어 있으면 background는 child를 아래 혹은 우로 드래그할 때 보인다.

  • secondaryBackground
    child 아래에 있어서 child widget을 드래그 해야 보이는 widget
    background widget이 존재해야만 의미가 있고 child를 위 혹은 좌로 드래그 할 때 보인다.

  • direction
    드래그 하는 방향
    default는 DismissDirection.horizontal

  • onDismissed
    child가 화면에서 사라지고 난 후에 호출

  • confirmDismiss
    dismiss가 동작하기전 유저에게 확인할 기회를 줌

example

  • 리스트뷰 생성
ListView.separated(
 separatorBuilder: (context, index) {
  return const SizedBox(
   height: 10,
  );
 },
 padding: const EdgeInsets.all(10),
 itemCount: snapshot.data!.length,
 itemBuilder: (context, index) {
  var food = snapshot.data![index];
   return FoodInfo(food: food);
  },
),
  • item을 Dismissible로 감싸기
    key는 item을 구별하기위한 고유 값
    key값으로 db에서 자동생성하는 primary key를 사용했지만 오류가 발생
    key값을 UniqueKey() 로 설정하니 해결

  Widget build(BuildContext context) {
    return Dismissible(
      key: Key("${food.id}"),
      child: Container(
        padding: const EdgeInsets.all(1),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(45),
          color: Colors.blue.shade100,
        ),
        ...
      ),
    );
  }
  • onDismissed
 Widget build(BuildContext context) {
    return Dismissible(
      key: Key("${food.id}"),
      onDismissed: (direction) {
        deleteFood(food.id);
      },
  • confirmDismiss
confirmDismiss: (direction) {
        return showDialog(
            context: context,
            builder: (ctx) {
              return AlertDialog(
                title: const Text('삭제'),
                content: Text('${food.name} 을/를 빼겠습니까?'),
                actions: <Widget>[
                  ElevatedButton(
                    onPressed: () {
                      return Navigator.of(context).pop(false);
                    },
                    child: const Text('취소'),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      return Navigator.of(context).pop(true);
                    },
                    child: const Text('삭제'),
                  ),
                ],
              );
            });
      },
  • direction
direction: DismissDirection.endToStart,
  • background
background: Container(
        decoration: BoxDecoration(
          color: Colors.red,
          borderRadius: BorderRadius.circular(45),
        ),
        padding: const EdgeInsets.symmetric(horizontal: 10),
        alignment: Alignment.centerRight,
        child: const Icon(
          Icons.delete_forever,
          color: Colors.white,
        ),
      ),
  • Item 전체 부분
import 'package:flutter/material.dart';
import 'package:refrigerator/database/foot_db.dart';
import 'package:refrigerator/model/food_model.dart';

class FoodInfo extends StatelessWidget {
  FoodInfo({
    super.key,
    required this.food,
  });

  final Food food;
  final FoodProvider foodProvider = FoodProvider();

  void deleteFood(int id) {
    foodProvider.delete(id);
  }

  
  Widget build(BuildContext context) {
    return Dismissible(
      key: Key("${food.id}"),
      onDismissed: (direction) {
        deleteFood(food.id);
      },
      confirmDismiss: (direction) {
        return showDialog(
            context: context,
            builder: (ctx) {
              return AlertDialog(
                title: const Text('삭제'),
                content: Text('${food.name} 을/를 빼겠습니까?'),
                actions: <Widget>[
                  ElevatedButton(
                    onPressed: () {
                      return Navigator.of(context).pop(false);
                    },
                    child: const Text('취소'),
                  ),
                  ElevatedButton(
                    onPressed: () {
                      return Navigator.of(context).pop(true);
                    },
                    child: const Text('삭제'),
                  ),
                ],
              );
            });
      },
      direction: DismissDirection.endToStart,
      background: Container(
        decoration: BoxDecoration(
          color: Colors.red,
          borderRadius: BorderRadius.circular(45),
        ),
        padding: const EdgeInsets.symmetric(horizontal: 10),
        alignment: Alignment.centerRight,
        child: const Icon(
          Icons.delete_forever,
          color: Colors.white,
        ),
      ),
      child: Container(
        padding: const EdgeInsets.all(1),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(45),
          color: Colors.blue.shade100,
        ),
        child: Container(
          padding: const EdgeInsets.symmetric(
            vertical: 5,
            horizontal: 10,
          ),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(45),
            color: Colors.white,
          ),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Flexible(
                flex: 2,
                child: Center(
                  child: Text(
                    food.name,
                    style: const TextStyle(
                      fontSize: 20,
                    ),
                  ),
                ),
              ),
              Flexible(
                flex: 1,
                child: Center(
                  child: Row(
                    children: [
                      Text(
                        food.quantity,
                        style: const TextStyle(
                          fontSize: 20,
                        ),
                      ),
                      Text(
                        food.unit,
                        style: const TextStyle(
                          fontSize: 10,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              Flexible(
                flex: 4,
                child: Center(
                  child: Column(
                    children: [
                      Text("구입날짜 : ${food.purchaseDate}"),
                      Text("유통기한 : ${food.expirationDate}"),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

참조
Jaeheee

0개의 댓글