【Flutter】Sliverを基本から
はじめに
この記事では Sliver
について、Flutter初心者向けに説明しています。そのため詳細よりも全体感を掴むことに重きをおいています。何となく使ったことがある、という状態を抜け出す一助になれば幸いです。
Sliverとは
Sliverとは、スクロール可能な領域です。
「破片にする、分割する」という意味の通り、スクロールできる領域の断片となります。
スクロールを実現するためのウィジェットは、内部的にSliverを使用しています。
SingleChildScrollView
スクロールを実装するにあたって、最もシンプルなウィジェットの1つとして SingleChildScrollView
があります。 これは、そのChild要素を1つのSliverとしてスクロール可能にするウィジェットです。
ListView
スクロールのパフォーマンスを考慮するなら、ListView
ウィジェットが役立ちます。これは子要素を複数のSliverに分割してスクロール可能にするウィジェットです。画面内のSliverのみが実際にレンダリングされるため、小要素がたくさんある場合はパフォーマンスに優れています。 GridView
なども同様です。
スクロール領域をまとめる
複雑なスクロールUIを実現するために、複数のSliverをまとめる必要があったりします。例えば、画面上にListView
とGridView
を半分ずつ表示する場合、一度のスクロール操作で動かせるのは、ListView
とGridView
のどちらか1つだけです。
ListView
とGridView
を組み合わせる例は極端ですが、スクロールに応じてアニメーションするAppBarなども同じです。一度のスクロール操作で異なるSliverの操作を行うことで、複雑なスクロールUIを実現することができます。
実装の例
CustomScrollView
Sliverを扱うWidgetはたくさんありますが、その中からまずは CustomScrollView
を見てみます。
以下は、公式ドキュメントのサンプルコードです。
CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
...,
),
SliverGrid(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
...,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(...);
},
childCount: 20,
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(...);
},
),
),
],
)
ポイント
-
children
ではなくslivers
(Sliver = スクロール片 を子要素とする)- Sliver以外を与えることはできません
- sliversの中には、
delegate
を要求するものがあります- そのsliverが特別に要求する情報や関数です
- どんなdelegateが必要かは使用するsliverによって異なります
- WidgetのContsraintsやリストのサイズを指定するなどが多い印象です
Sliverが要求されている場合、当然ながらSliver以外のWidgetを与えることはできません。例えばCustomScrollView
の中でPadding
を設定したい場合は SliverPadding
Widgetを使用します。
このように Sliver〇〇
の形になっているWidgetがあるので、使いたいWidgetにSliver
のprifixをつけて探してみると、イメージするレイアウトが組みやすいかと思います。
まとめ
- 普段意識していなくても、実は内部的にSliverを使用している
- 複数のSliverをまとめて制御する場合、Sliverを自分で扱うためのWidgetが利用できる
- Sliver系のWidgetはパラメータとしてdelegateを要求することがある
- よく使用するWidgetのSliverバージョンが存在する
Discussion