[読書会]GridView クラスについて

本サイトは api.flutter.dev/GridView のリファレンスブログです。

1.GridView クラス

1-1.一般的なGridView

(1)スクロール可能な2次元のウィジェット配列

GridViewは、スクロール可能な2次元のウィジェット配列です。ウィジェットが行や列に沿って並べられ、グリッド形式のレイアウトを構成します。スクロール方向は、縦または横に設定することができ、グリッド全体がスクロールして表示されます。

(2)スクロール方向

グリッドの主軸方向は、スクロールする方向(scrollDirection)です。デフォルトでは縦方向(Axis.vertical)にスクロールしますが、横方向(Axis.horizontal)にスクロールするように設定することも可能です。これにより、グリッドが縦方向または横方向に無限にスクロールできるようになります。

(3)一般的なGridViewのレイアウト方法

① GridView.count

GridView.countは、グリッドのクロス軸(スクロール方向と直交する軸)に沿って固定された数のタイルを作成します。たとえば、クロス軸に3つのタイルを並べるグリッドを作成したい場合に使用します。クロス軸とは、スクロール方向に対して垂直な軸です。縦スクロールの場合、クロス軸は横方向(X軸)です。

② GridView.extent

GridView.extentは、タイルの最大クロス軸の幅(または高さ)を指定して、レイアウトを作成します。各タイルがこの最大幅以内に収まるように配置され、柔軟なグリッドレイアウトを実現します。これにより、画面幅に応じて動的にタイルの数が変わるレイアウトが可能です。

1-2.カスタムレイアウトの作成

SliverGridDelegateをカスタマイズすると、任意の2Dレイアウトを作成できます。これには、標準的なグリッド配置に限らず、非整列な配置や重なり合う配置も含まれます。SliverGridDelegateは、子ウィジェットをどのようにグリッド内に配置するかを定義するためのクラスです。

1-3.大量のウィジェットを扱う場合

GridView.builder

多数のウィジェット(無限スクロールを含む)を効率的に表示するには、GridView.builderコンストラクタを使用します。これにより、必要に応じてウィジェットを動的に作成し、メモリの効率化を図ります。この場合、gridDelegateには次のいずれかを使用します。

SliverGridDelegateWithFixedCrossAxisCount

 クロス軸に沿って固定された数のタイルを表示します。

SliverGridDelegateWithMaxCrossAxisExtent

 クロス軸に沿ってタイルの最大幅を指定し、それに基づいてレイアウトを決定します。

1-4.カスタムSliverChildDelegateを使用する場合

GridView.custom

カスタムのSliverChildDelegateを使用するには、GridView.customを使います。
SliverChildDelegateは、子ウィジェット生成管理方法制御するクラスで、カスタムのデリゲートを使って、子ウィジェット動的生成キャッシュ管理など、細かい挙動定義できます。

1-5.線形の配列(リスト)を作成する場合

子ウィジェットが1次元の線形配列(リスト)として並ぶ場合は、ListViewを使います。
GridViewが2次元のグリッドに対して、ListViewは縦や横方向に1列でウィジェットを並べるレイアウトです。

1-6.初期スクロール位置の制御

ScrollController.initialScrollOffset

スクロールビューの初期スクロールオフセット最初に表示する位置)を制御するには、ScrollControllerinitialScrollOffsetプロパティを使用します。これにより、GridViewが初めて表示された時に、特定の位置から表示開始することができます。

2.CustomScrollView

GridViewは、シンプルな2Dグリッドを表示するためのウィジェットですが、より柔軟なレイアウトを実現したい場合には、CustomScrollViewとSliverを使う必要があります。具体的には、グリッドとリストを組み合わせたり、SliverAppBarを追加したりするときです。

2-1.GridViewとCustomScrollViewの関係

GridViewは、基本的にCustomScrollViewに1つのSliverGridを含んだ構造です。つまり、GridViewの内部では、SliverGridが使われて2Dのグリッドレイアウトが実現されています。

したがって、もしGridViewが十分でない場合(例: グリッドとリストを混在させたい場合や、SliverAppBarと組み合わせたい場合など)、コードを直接CustomScrollViewに移行するのは比較的簡単です。

2-2.GridViewのプロパティとCustomScrollViewのプロパティの対応関係

GridViewの次のプロパティは、CustomScrollViewの同名のプロパティに直接マッピングされます。

  • scrollDirectionスクロール方向
  • reverse逆方向スクロール
  • controllerスクロールコントローラ
  • primary
  • physicsスクロールの挙動
  • shrinkWrapビューのサイズ制御

これらのプロパティはCustomScrollViewでも同じように使用できるので、GridViewからCustomScrollViewに移行しても、スクロールの挙動に関しては特別な調整が必要ありません。

2-3.CustomScrollView.sliversプロパティ

CustomScrollViewのsliversプロパティには、複数のSliverをリストとして渡すことができます。GridViewから移行する場合、sliversプロパティにはSliverGridが必要です。これは、GridViewのグリッド部分に相当します。

2-4.childrenDelegateとgridDelegateの対応関係

GridViewchildrenDelegateは、SliverGriddelegateに対応します。
これにより、SliverGrid子ウィジェットどのように生成し、管理するか決定します。

GridViewgridDelegateは、SliverGridgridDelegateに対応します。
gridDelegateは、グリッドレイアウト(例えば、列数やタイルのサイズ)を定義する役割を果たします。

2-5.GridViewのコンストラクタとSliverChildDelegateの対応関係

GridView.countGridView.extentchildren引数は、SliverChildListDelegateに対応します。
このデリゲートは、リストで提供されるウィジェットを直接表示します。

一方、GridView.builderで提供されるitemBuilderchildCount引数は、SliverChildBuilderDelegateに対応します。このデリゲートは、スクロール位置に応じて子ウィジェット動的生成します。

2-6.GridView.countとGridView.extentの移行

GridView.countGridView.extentで定義されたグリッドは、それぞれSliverGrid.countSliverGrid.extent簡単に移行できます。これにより、列数やタイルの最大幅を指定して、同様のグリッドを作成できます。

2-7.paddingプロパティの移行

GridViewpaddingプロパティは、CustomScrollViewではSliverPaddingを使って表現されます。
具体的には、SliverPaddingCustomScrollView.sliversリスト追加し、そのとしてSliverGrid指定します。こうすることで、グリッド全体パディング適用できます。

2-8.CustomScrollViewへの移行後の拡張

CustomScrollViewに移行した後、他のSliver追加することが可能です。
例えば、SliverListリスト形式のレイアウト)やSliverAppBarスクロール可能なアプリバー)をsliversリスト含めることで、より複雑なレイアウト作成できます。
これにより、グリッドリスト組み合わせたり、スクロール可能アプリバー使用した複雑なレイアウト実現できます。

3.セッション中のスクロール位置を保持する仕組み

3-1.スクロール位置の保持

スクロールビューは、セッション中のスクロール位置を自動的に保持しようとします。この保持は、PageStorageという仕組みを使用して行われます。PageStorageは、アプリ内での一時的なデータ保存に使用され、ウィジェットが破棄されて再作成された場合でも、スクロール位置などの状態が維持されるようにします。

これにより、例えば、ユーザーが画面をスクロールして別の画面に遷移した後、再び元の画面に戻ったときに、スクロール位置が以前と同じ場所に保たれるというユーザー体験が提供されます。

3-2.ScrollController.keepScrollOffset

スクロール位置の保持機能は、ScrollControllerkeepScrollOffsetプロパティfalseに設定することで無効にできます。デフォルトでは、このプロパティはtrueに設定されており、スクロール位置自動的保持されますが、特定の状況ではこの機能をオフにしたい場合もあります。

例えば、スクロール位置を保持したくない場合や、新しいスクロール位置から再開したい場合は、このプロパティをfalseに設定します。

3-3.PageStorageKeyの利用

スクロールビューが複数存在する場合、それぞれのスクロール位置を区別するためにPageStorageKeyを使用することが推奨されています。PageStorageKeyは、PageStorage内でウィジェットの状態を保存する際の一意の識別子として機能します。

同じスクロールビューが複数の異なる場所で使われている場合(例えば、リストビューが複数ある場合)、PageStorageKeyを使ってそれぞれのスクロール位置を正しく識別し、混同を避けることができます。

例えば、2つの異なるリストビューが同じページに表示されている場合、PageStorageKeyを使ってそれぞれに異なるキーを割り当てれば、それぞれのリストビューのスクロール位置が個別に保持されます。

コメントを残す