[Flutter/Dart]項目の並び替えと削除ができるリスト

2020年11月21日

項目を自由に並び替えたり削除したりできるリストの作り方です。実際の動作は以下のようになります。

サンプルコード

並び替え可能なリストはクラス ReorderableListView によって作成します。削除可能なリスト項目は Dismissible を使用します。

並び替えの機能はリスト全体に適用されますが、削除の機能は項目ごとです。並び替え可能なリストである ReorderableListView の子要素として、削除可能な Dismissible なリスト項目を追加していきます。

サンプルコードを以下に記載します。

reorderable_and_dismissible_list.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

// リスト項目のデータ構造
class MyData {
  String id;
  String name;
  int age;

  MyData(this.id, this.name, this.age);
}

// リスト項目
List<MyData> dataList = <MyData>[
  MyData('item1', 'A', 23),
  MyData('item2', 'B', 26),
  MyData('item3', 'C', 35),
  MyData('item4', 'D', 42),
];

class MyList extends StatefulWidget {
  MyList({Key key}) : super(key: key);

  @override
  MyListState createState() => MyListState();
}

class MyListState extends State<MyList> {
  
  // リスト項目となる削除可能なウィジェットを作成
  Widget buildItem(MyData item, int index) {
    return Dismissible(
        key: Key('${item.id}'), // 項目が特定できるよう固有の文字列をキーとする
        background: Container(color: Colors.red), // スワイプしているアイテムの背景色
        confirmDismiss: (direction) async {
          // 削除するか確認する
          return await showDialog(
            context: context,
            builder: (BuildContext context) {
              return AlertDialog(
                title: Text('確認ダイアログ'),
                content: Text('本当に削除しますか?'),
                actions: <Widget>[
                  TextButton(
                    onPressed: () => Navigator.of(context).pop(false),
                    child: Text('CANCEL'),
                  ),
                  TextButton(
                      onPressed: () => Navigator.of(context).pop(true),
                      child:
                          Text('DELETE', style: TextStyle(color: Colors.red))),
                ],
              );
            },
          );
        },
        onDismissed: (direction) {
          // 削除時の処理
          setState(() {
            dataList.remove(item);
          });
        },
        // 各項目のレイアウト
        child: ListTile(
          tileColor: Theme.of(context).cardColor,
          title: Text(item.name,
              style: TextStyle(
                  fontWeight: FontWeight.bold, fontSize: 24, height: 1.2)),
          subtitle: Text('AGE: ${item.age}'),
          trailing: Icon(Icons.chevron_right),
          onTap: () {
            print(item.name);
          },
        ));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('削除と並び替えができるリスト'),
        ),
        body: ReorderableListView(
            onReorder: (int oldIndex, int newIndex) {
              if (newIndex > oldIndex) {
                // 元々下にあった要素が上にずれるため一つ分後退させる
                newIndex -= 1;
              }

              // 並び替え処理
              MyData data = dataList[oldIndex];
              setState(() {
                dataList.removeAt(oldIndex);
                dataList.insert(newIndex, data);
              });
            },
            padding: EdgeInsets.only(top: 4),
            children: dataList
                .asMap()
                .map((i, item) => MapEntry(i, buildItem(item, i)))
                .values
                .toList()));
  }
}

reorderable_and_dismissible_list.dart と名付けて保存し、runApp を行うファイル(main.dart)で読み込みます。

List である dataList に表示したい項目を追加してください。ウィジェット MyList を読み込めば、削除と並び替えが可能なリストが表示されます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です