💨

Flutter Grid.builder無限スクロール作成方法@初心者

2024/10/05に公開

無限スクロール方法

実務で無限スクロールを作成することになったのでそちらをかきこ。
インスタで投稿をみるときスクロールするかと思いますが、その画面のイメージです。

無限数量作成するのではなく、
例えば、APIで取得したリストの値が30あります。
その30の値をスクロールしても表示し続ける様なイメージです。

【 30までスクロールで表示したら、indexが0に戻る 】

上記で今回無限スクロールを作成します。

本題のコード

使用したのは、Grid.customを利用しました。
Grid.builderについては下記でわかりやすく説明されています。
https://flutter.ctrnost.com/basic/layout/gridview/

実際のコードは下記。

GridView.custom(
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 3,
                crossAxisSpacing: 12,
                childAspectRatio: 0.58,
              ),
              childrenDelegate: SliverChildBuilderDelegate(
                (context, index) {
                  final itemIndex =
                      index % aoList.length; 
                  return mukagenjujutsu(
                    mugen: itemIndex,
                  );
                },
              ),
            ),

それぞれ説明します。

GridView.custom

  • GridView.custom
    カスタム可能な子Wedgetを作成するために利用。
    子widgetが無限に作成される対象

https://api.flutter.dev/flutter/widgets/GridView/GridView.custom.html

gridDelegate プロパティ

  • gridDelegate プロパティ
    グリッドのレイアウトを定義
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
 crossAxisCount: 3,         // 横に並べるアイテムの数
  crossAxisSpacing: 12,      // アイテム間の横方向の間隔
  childAspectRatio: 0.58,    // アイテムの縦横比(幅に対する高さの比率)
),
  • crossAxisCount: 3
    横方向(クロスアクシス)に3つのアイテムを並べる。

  • crossAxisSpacing: 12
    横方向のアイテム間の間隔を12ピクセルに設定。

  • childAspectRatio: 0.58
    各アイテムの縦横比を設定します。
    縦横比 = 幅 / 高さ。つまり、幅が1に対して高さが1/0.58 ≈ 1.72倍。

childrenDelegate プロパティ

  • childrenDelegate
    アイテム(子widget)を動的に作成するため /// ここが重要

  • SliverChildBuilderDelegate
    上記でアイテムを必要な時にビルドする

剰余演算子

無限スクロールするにあたってここが最重要ポイントです。

 childrenDelegate: SliverChildBuilderDelegate(
                (context, index) {
                  final itemIndex =
                      index % aoList.length; 
                  return mukagenjujutsu(
                    mugen: itemIndex,
                  );
                },
              ),

余剰演算子ってなんぞやなので、下記でやり方です。

例えば、aoList.length がリストの要素数(例えば 5)であるとする。
インデックスが 0 から 4 までの範囲であれば、問題なくリスト内の要素を取得可能。

しかし、インデックスがリストの長さを超えると、存在しない要素を参照しようとしてエラーが発生します。これを避けるために、インデックスをリストの範囲内に収める必要がある。

そこで余剰演算子を使う。

index = 5 のとき、5 % 5 = 0 となり、最初の要素に戻る。
要素が無いエラーがおきない。
以降も同様に、index が 5 ずつ増加するごとに itemIndex が 0 になる。

index index % aoList itemIndex(余りの数)
0 0 % 5 0
1 1 % 5 1
2 2 % 5 2
3 3 % 5 3
4 4 % 5 4
5 5 % 5 0 ←最初に戻る

つまり、index が aoList.length の倍数になると、余りが 0 となり、インデックスが 0 に戻ります。
これにより、リストの最初の要素から再びアイテムが表示されるということです。

これで無限スクロールの出来上がりです。

動的なwidgetListを作成するなら.builderがおすすめです。

必要な分だけ表示してくれるのでアプリのパフォーマンスも良くなります。

上記でこんなに簡単につくれるとおもわなかっったので学びになりました~

Discussion