🐰
【Flutter】ListViewの縦方向表示アイテム数を指定する
はじめに
「ListView
を使いたいけど、縦方向に表示されるアイテム(Widget
)数はxxだけにしたい」という時がありますよね?
何を言っているかというと、縦方向のアイテム数を5に設定すると、以下のように表示されて
以下のようにウィンドウのサイズを変更してもアイテム数は5のままなListView
を使いたいというわけです。
(スクロール中は見切れたアイテムが表示されるので正確には6アイテム見えるのですが。)
こういうときありますよね?(ないか)
これを実現してくれる方法を見つけられなかったので、Widgetを自作しました。
自作したWidget
class ListViewWithViewItemCount extends StatelessWidget {
const ListViewWithViewItemCount({
super.key,
required this.viewItemCount,
required this.children,
});
final int viewItemCount;
final List<Widget> children;
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
return ListView(
itemExtent: constraints.maxHeight / viewItemCount,
children: children,
);
},
);
}
}
LayoutBuilder
を用いることでListView
の親Widgetのconstraintsを知ることができます。
constraints.maxHeight
と表示アイテム数から、1アイテムの高さを計算し、ListView
のitemExtent
に指定します。
これで、ListView
の1スクロール画面内には指定した個数のアイテムだけが表示されます。
使用例
以下の使用例は冒頭に載せた画面のアプリケーションの実装です。
lib/main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
+ child: ListViewWithViewItemCount(
+ viewItemCount: 5,
+ children: [
+ for (final i in List.generate(30, (index) => index))
+ ListTile(
+ title: Text('item$i'),
+ subtitle: Text('subtitile$i'),
+ leading: const Icon(Icons.settings),
+ trailing: const Icon(Icons.arrow_forward),
+ ),
+ ],
+ ),
),
);
}
}
おわりに
LayoutBuilder
を使ったことがなかったため、実現方法が全くわからず四苦八苦しました。
(Rendering中、Widgetのサイズ変更を通知させて動的にアイテムのサイズを変更して例外発生したり。)
他にもっと良い方法をご存じの方はぜひ教えてください。。。
参考文献
迷走時
- Rendering時のサイズを知ることでアイテムの高さを指定しようとしていたとき
Discussion