(2020/03/10) 追記: 再修正
(2020/02/10) 追記: ときどきみていただいているようなので修正
codelabs の Write Your First Flutter App, part 2 での使われ方だと、自動で補充されるので挙動がちょっとわかりにくい。
いざ自分で書く際に、ListView.builder
で作って入れるだけだと、サイズが計算できずにエラーになったりする。
Flutter開発する前に知っておきたい35のWidget一覧
個数が既知で固定の場合、Column
のように ListView(children: list)
で作っても良いですが、基本的には動的になると思うので、ListView.builder
や ListView.separated
で構築します。
Expanded などでつつんであげる
レイアウト計算用に入れ物がいる場合、Expanded
に入れたり、なんらかの形で高さを自動計算できるようにしておかないと駄目なことがある。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Hoge')),
body: Column(children: [
new Expanded(
child: buildListView()
),
もちろん、明示的に高さを指定しても良いです。
Container(
height: 200.0,
child: ListView.separated(
itemCount: list.length,
itemBuilder: (BuildContext context, int index) { // 以下略
アイテム数が既知なら ListView() / ListView.separated
一番シンプルなのは、Widget[] を並べるもの
ListView(children:list);
区切りを挟みたい場合は、ListView.separated を使います。
itemBuilder, separatorBuilder でアイテムと区切りを生成します。
ListView.separated(
itemCount: list.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('${list[index]}'),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(),
);
必要に応じて、itemBuilder
の関数が呼ばれるので、index
に対応した項目を作ってあげます。
ここでは、シンプルに ListTile
を使っていますが、色々便利な Widget
があります。
- Card や SwitchListTile
- Dismissible でフリック削除対応
- flutter_slidable でフリックでアクションを出す
separatorBuilder
は標準の Divider
を使っていますが、独自の区切りにも出来るはず。
項目数が不明なら ListView.builder
itemCount
を指定しないと、サイズが埋まるまで延々と itemBuilder
を呼ぶような挙動をします。
Flutter ListView Example | Displaying Dynamic Contents Tutorial
範囲外は null を返します
Widget buildListView() {
return ListView.builder(
padding: const EdgeInsets.all(16.0),
itemBuilder: (context, i) {
if (i.isOdd) return Divider();
final index = i ~/ 2;
if (list.length <= index) {
return null;
}
return ListTile(
title: Text(list[index].toString()),
);
});
}