この記事で解決する問題
入れ子のリスト(リストの中にあるリスト)を使う際に、builderがうまく機能しない。builderだと画面に見える部分のみ生成されるが、なぜか最初にすべて生成され、読み込みに時間がかかる。
なぜ機能しないのか
親がスクロール系のウィジェットのとき、子のリストが独立してスクロールできないようにNeverScrollableScrollPhysicsを使用できる。だが、これを使用しているとbuilderがスクロールしていない判定になり、buiderの特徴であるダイナミックなローディングが効かないため、一気に読み込むことになってしまう。
解決策と使用例
●CustomScrollViewを使用するCustomScrollViewを代用すると、Sliverが使えます。
Sliverとは、スクロールできる親ウィジェットの中の一部分です。
今回の場合、Sliversといういわばブロックのようなものを組み合わせて、それを親であるCustomScrollViewという一つのスクロールできるウィジェットにします。
そしてその各Sliverは、builderを使うことができます。
以下、使用例のコードです。
CustomScrollView(
slivers: [
SliverList(
// Listの要素をbuilderでつくる
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => Container(
margin: EdgeInsets.all(10),
height: 100,
color: Colors.amber,
child: Text('Item $index'),
),
childCount: 50, //list.lengthなどにする場合が多い
),
),
// Gridの場合 (Sliver内で複数のList, Gridを併用可能)
SliverGrid(
// 子Widgetの大きさや位置を設定
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 4,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) => Container(
alignment: Alignment.center,
color: Colors.cyan,
child: Text('Item $index'),
),
childCount: 50,
),
),
],
);
以上、参考になれば幸いです。