Flutter Dismissible Widjet スワイプでのリスト項目の削除方法

April 19, 2021

リストを、スワイプで削除する際に便利なFlutterのウィジェットDismissibleに関するメモ

Dismissibleでラップする

ListTileなど、アイテムを構成しているWidgetをDismissible()でラップすると使えます。下記のような形。

サンプルコード

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:todo_app/screens/task/task_model.dart';
import 'package:todo_app/screens/task_new/task_newpage.dart';

class TaskPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (_) => TaskListModel()..fetchTasks(),
        child: Consumer(builder: (context, model, child) {
          final tasks = model.tasks;
          final ListTiles = tasks
              .map((task) => Card(
                    color: Colors.green,
                    //スワイプで削除
                    child: Dismissible(
                      key: Key(task.documentID),
                      direction: DismissDirection.endToStart,
                      background: Container(
                        alignment: Alignment.centerRight,
                        color: Colors.redAccent[700],
                        child: Padding(
                            padding: EdgeInsets.fromLTRB(10.0, 0.0, 20.0, 0.0),
                            child: Icon(Icons.delete, color: Colors.white)),
                      ),
                      confirmDismiss: (DismissDirection direction) async {
                        return await showDialog(
                          context: context,
                          builder: (BuildContext context) {
                            return AlertDialog(
                              title: Text("確認"),
                              content: Text("削除します。よろしいですか?"),
                              actions: [
                                FlatButton(
                                    onPressed: () async {
                                      Navigator.of(context).pop(true);
                                      await model.deleteTask(task);
                                    },
                                    child: const Text("削除")),
                                FlatButton(
                                  onPressed: () =>
                                      Navigator.of(context).pop(false),
                                  child: const Text("キャンセル"),
                                ),
                              ],
                            );
                          },
                        );
                      },
                      child: ListTile(
                        title: Text(task.title),
                        onTap: () {
                          Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => TaskNewPage(
                                      tasks: task,
                                    ),
                                fullscreenDialog: true),
                          );
                        },
                      ),
                    ),
                  ))
              .toList();
          return ListView(padding: EdgeInsets.all(20), children: ListTiles);
        }));
  }
}

主な引数

key

ユニークなキーを指定してあげる必要があります。

background

アイテムをスワイプした時の背景を指定することができます。スワイプすると背景色などを装飾することができます。

direction

スワイプできる方向を指定します。

 direction: DismissDirection.endToStart,
  • 右から左:DismissDirection.endToStart 
  • 左から右:DismissDirection.startToEnd
  • 右から左・左から右:DismissDirection.horizontal
  • 下から上・上から下:DismissDirection.vertical
  • 下から上:DismissDirection.up
  • 上から下:DismissDirection.down

confirmDismiss

スワイプのアニメーションが終わったタイミングで呼ばれます。
まだWidgetが破棄されていないため、本当に処理を実行して良いか等の確認処理を入れたい時に便利です。

onDismissed

スワイプでWidgetが破棄され、アニメーションが終わったタイミングで呼ばれます。
実際のデータの削除処理などはここで行うことになります。

また、どの方向にスワイプされたか取得したかを取得できるのが特徴で、スワイプ方向によって処理を分けることもできます。

Tags