Open2
ListViewとは?

1. ListViewとは
ListViewは Flutter で最も一般的に使用されるスクロール可能なウィジェットです。子ウィジェットを線形に配置し、スクロール方向に沿って順番に表示します。
主な特徴:
- スクロール可能な要素を簡単に実装できる
- 子ウィジェットは横方向または縦方向に配置可能
- メモリ効率の良い遅延ロードをサポート
- カスタマイズ性が高い
2. ListViewの4つの構築方法
2.1 デフォルトコンストラクタ
ListView(
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 50,
color: Colors.amber[600],
child: const Center(child: Text('項目 A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('項目 B')),
),
],
)
使用場面:
- 少ない数の固定項目を表示する場合
- すべての子ウィジェットを一度に構築する必要がある場合
2.2 ListView.builder
final List<String> items = <String>['A', 'B', 'C'];
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('項目 ${items[index]}'),
);
},
)
使用場面:
- 大量のデータを表示する場合
- 無限スクロールを実装する場合
- メモリ効率を重視する場合
2.3 ListView.separated
ListView.separated(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('項目 ${items[index]}'),
);
},
separatorBuilder: (context, index) => const Divider(),
)
使用場面:
- リスト項目間に区切り線などを入れたい場合
- 固定数の項目がある場合
2.4 ListView.custom
ListView.custom(
childrenDelegate: SliverChildBuilderDelegate(
(context, index) => ListTile(
title: Text('項目 $index'),
),
),
)
使用場面:
- より詳細なカスタマイズが必要な場合
- 特殊なスクロール動作を実装する場合
3. 重要なプロパティ
3.1 基本プロパティ
ListView(
scrollDirection: Axis.vertical, // スクロール方向
reverse: false, // リストの逆順表示
controller: scrollController, // スクロールコントローラー
physics: ScrollPhysics(), // スクロールの物理演算
padding: EdgeInsets.all(8.0), // パディング
)
3.2 パフォーマンス最適化プロパティ
ListView.builder(
itemCount: items.length,
cacheExtent: 100.0, // キャッシュ範囲
addAutomaticKeepAlives: true, // 状態保持
addRepaintBoundaries: true, // 再描画の最適化
)
4. メモリ管理とライフサイクル
4.1 要素の作成
// 表示領域に入った時に要素が作成される
ListView.builder(
itemBuilder: (context, index) {
print('要素 $index を作成');
return ListTile(title: Text('項目 $index'));
},
)
4.2 要素の破棄
画面外にスクロールされた要素は自動的に破棄されます。ただし、以下の方法で状態を保持できます:
// KeepAliveを使用した状態保持
class MyListItem extends StatefulWidget {
_MyListItemState createState() => _MyListItemState();
}
class _MyListItemState extends State<MyListItem>
with AutomaticKeepAliveClientMixin {
bool get wantKeepAlive => true; // 状態を保持
Widget build(BuildContext context) {
super.build(context);
return ListTile(
title: Text('保持される項目'),
);
}
}
5. エッジケースの処理
5.1 空のリストの処理
Widget build(BuildContext context) {
return items.isEmpty
? Center(child: Text('データがありません'))
: ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(items[index]),
);
},
);
}
5.2 スクロール位置の保持
ListView(
key: PageStorageKey('listView'), // スクロール位置を保持
children: items.map((item) => ListTile(
title: Text(item),
)).toList(),
)
6. パフォーマンス最適化のベストプラクティス
- 適切なコンストラクタの選択
- キャッシュの活用
- 要素の再利用
- 画像の遅延ロード
- スクロール位置の最適化