📦
[Flutter] ReorderableListViewで一部を並び替えられないようにする
はじめに
Flutterでリストの並び替えを可能にするReorderableListView
を使っていて、一部を並び替えられないようにしたいケースに遭遇した際の記録です。
イメージしやすいよう具体例を提示すると、以下のようなケースなどで使える内容かと思います。
- TODOリストで未完了のTODOは並び替えられるようにしたいけど、完了済のTODOは並び替えられないようにしたい
方針
プロパティとして、footer
というのが用意されているのでそれを使うだけでした。
A non-reorderable footer item to show after the items of the list.
If null, no footer will appear after the list.
まさにですね。
コード例
せっかくなので(?)、コード例を載せて終わろうと思います。
※ ReorderableListViewのドキュメントに記載のあるサンプルコードに手を入れて、強引に動かしているので一部違和感のある箇所ありますが、本記事の本質ではないのでご理解いただけると幸いです..。
import 'package:flutter/material.dart';
/// Flutter code sample for [ReorderableListView].
void main() => runApp(const ReorderableApp());
class ReorderableApp extends StatelessWidget {
const ReorderableApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('ReorderableListView Sample')),
body: const ReorderableExample(),
),
);
}
}
class ReorderableExample extends StatefulWidget {
const ReorderableExample({super.key});
State<ReorderableExample> createState() => _ReorderableListViewExampleState();
}
class _ReorderableListViewExampleState extends State<ReorderableExample> {
final List<int> _items = List<int>.generate(3, (int index) => index);
final List<int> _notReorderItems =
List<int>.generate(8, (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);
return ReorderableListView(
padding: const EdgeInsets.symmetric(horizontal: 40),
onReorder: (int oldIndex, int newIndex) {
setState(() {
if (oldIndex < newIndex) {
newIndex -= 1;
}
final int item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
footer: ListView(
shrinkWrap: true,
children: <Widget>[
for (int index = 3; index < _notReorderItems.length; index += 1)
ListTile(
key: Key('$index'),
tileColor:
_notReorderItems[index].isOdd ? oddItemColor : evenItemColor,
title: Text('Item ${_notReorderItems[index]}'),
),
],
),
children: <Widget>[
for (int index = 0; index < _items.length; index += 1)
ListTile(
key: Key('$index'),
tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
title: Text('Item ${_items[index]}'),
),
],
);
}
}
ほとんどがサンプルコードのままで、追加したのはfooterの箇所くらいです。
動かすと以下のようになります。
indexが0,1,2のアイテムは並び替えできるものの、3以降のアイテム(コード上では_notReorderItems
)は並び替えられないことが確認できます。
おわりに
「一般的に考えうる実現したいこと」は用意されていることが多々あるので、
ドキュメントをしっかり読んで、車輪の再発明をしないようにしていきたいものです。
Discussion