flutterのListviewでDrag and Dropを使う

こんにちは。
FlutterのListviewでDrag and Dropで要素のソートをしてみたいと思います。

ReorderableListViewでリストのDrag and Drop

ReorderableListViewを使って実現します。
https://api.flutter.dev/flutter/material/ReorderableListView-class.html

リストの準備

リスト用のMyCategoryクラスとSettingクラスを作成して、Settingクラスが呼び出されたら、リストを表示します。

import 'package:flutter/material.dart';

class MyCategory {
  String title;
  String subtitle;
  Color color;
  String key;
  MyCategory(
    this.title,
    this.subtitle,
    this.color,
    this.key,
  );
}

class Settings extends StatefulWidget {
  @override
  _SettingsState createState() => _SettingsState();
}

class _SettingsState extends State<Settings> {
  List<MyCategory> cateList;
  final SlidableController slidableController = SlidableController();

  @override
  void initState() {
    super.initState();

    cateList = [
      MyCategory('List 1', "Here is list 1 subtitle",Color(0xffe64571),'1'),
      MyCategory('List 2', "Here is list 2 subtitle",Color(0xffedc549),'2'),
      MyCategory('List 3', "Here is list 3 subtitle",Color(0xffccb485),'3'),
      MyCategory('List 4', "Here is list 4 subtitle",Color(0xffa59f49),'4'),
      MyCategory('List 5', "Here is list 5 subtitle",Color(0xffc5763a),'5'),
    ];
  }

要素の並べ替え

ReorderableListViewで並び替えをする場合は、onReorderコールバックを必ず追加する必要があります。また子供の要素にkeyを付ける必要があります。

class _SettingsState extends State<Settings> {
・・・・

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('AppBar Demo'),
    ),
    body: ReorderableListView.builder(
        itemCount: cateList.length,
        onReorder: (oldIndex, newIndex) {
          if (oldIndex < newIndex) {
            newIndex -= 1;
          }
          final MyCategory mycate = cateList.removeAt(oldIndex);
          setState(() {
            cateList.insert(newIndex, mycate);
          });
        },
      itemBuilder: (context, index) {
        return Card(
            key: Key(cateList[index].key),
            child: ListTile(
              title: Text(cateList[index].title),
              subtitle: Text(cateList[index].subtitle),
              leading: CircleAvatar(
                backgroundColor: cateList[index].color,
              ),
            ),
          ),
        );
      })
  );
}

コメントを残す

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

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)