TODOアプリなどでリストを作ることがあると思いますが、それらを並び替える機能が欲しいと思ったことありませんか? そんな時はreorderableListViewを利用しましょう。
reorderbleListviewの実装は簡単
表示に関してロジックもありますが、正直考える必要はありません。基本的にはコピペでほぼできてしまいます。以下は公式ページのコードを少し編集したものです。個人な好みですが、builder
メソッドを使っています。
class ReorderableExample extends StatefulWidget {
const ReorderableExample({super.key});
State<ReorderableExample> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<ReorderableExample> {
final List<int> _items = List<int>.generate(50, (int index) => index);
Widget build(BuildContext context) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
final Color evenItemColor = colorScheme.primary.withOpacity(0.15);
////////////////// ReoderableListViewの部分 //////////////////
return ReorderableListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 40),
itemCount: _items.length,
itemBuilder: (context, i) {
return ListTile(
tileColor: _items[i].isOdd ? oddItemColor : evenItemColor,
key: Key('$i'), //【注意①】keyが必須になります
title: Text('Item ${_items[i]}'),
);
},
onReorder: (int oldIndex, int newIndex) {
//【注意②】並び替え時のロジックは公式にも記載があり、あまり考える必要はありません。
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
//【注意③】実際はローカルやAPIを使っての、並び替えたデータの保存処理が必要です。
},
);
////////////////// ReoderableListViewの部分 //////////////////
}
}
注意1 アイテムにはKeyが必要
itemBuilder
の後のウィジェットにはkeyが必要となります。 最初はよく分からずReorderableListViewにkeyをつけていましたが、それは誤りなので注意しましょう。
注意2 並び替え時のロジックは考えない
onReorder
には並び替え時に呼び出すロジックを記載するのですが、公式のサンプルにはロジックの記載があります。真面目な方だと理解しようと考えるかもしれません。
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
しかし、これは並び替えに必須なロジックであり、いじる必要はありません。特に仕事の場合は納期などもあるので、コピペでも良いと思います。労力としては次に示す保存や表示において使うのが賢明です。
注意3 保存のためにorderをコンストラクターに設ける
個々のアイテムのコンストラクターには、通常name
やid
、createdAt
などがありますが、並び順を指定するint型のorder
も用意しておきましょう。
また、下記のように初期値や並び替え後の数値を保存すると、次に記載する表示の際に私は楽だと感じました。
新規のアイテムは、order:0,
並び変え後のアイテムは、order:アイテムリストのindex + 1
注意4 表示順 〜新規分も考えて〜
実際に表示する際には、ロジックも丁寧に考えてあげる必要があります。orderの順に表示するとは言え、2件以上新規作成でアイテムを作ると、order:0で重複してしまうからです。
ついては私は下記のように考えました。
第一優先キー order
第二優先キー createdAt
保存と表示はUIの10倍ぐらいかかった
私の実感ですが、UIの表示は本当にコピペですぐにできます。実際に並び替えができている感じがして楽しいです。しかし、その後のAPIを使って保存したり、新規に表示する際に正しく並び替えて表示する点はかなり手間で、UI作成の10倍くらい時間を使った気がします。
まとめ
並び替え機能を実装する際は、reorderbleListviewを使いましょう。ただし、その後の保存のロジックや、新規画面において正しい順で表示するためには一手間かかるので注意しましょう。
Discussion