虎視眈々と

Flutter × Firebaseを研究するアプリエンジニア

FlutterでGridViewのItemを格子状に表示する

f:id:superman199323:20181011212511p:plain

FlutterでGirdのアイテムを格子状に表示する

www.youtube.com

こんな形でGridのアイテムを格子状に表示する方法を書いていきます。

プラグインを導入する

flutter_staggered_grid_view というプラグインを導入します。

pub.dartlang.org

いつも通り pubspec.yml を編集します。

flutter_staggered_grid_view: ^0.2.2

実装

実装方法は複数あるので全ては紹介しませんが、基本的にGridViewの使い方に一手間加えたような実装方法になります。

先に最初に貼ったyoutubeの動画の再現コードをそのまま貼ります。

Widget _imageGrid() {
    return StreamBuilder(
      stream: Firestore.instance.collection("group")
          .document(widget.groupId)
          .collection("group_item")
          .orderBy("updated_at", descending: true)
          .snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) return Container();
        return CustomScrollView(
          slivers: <Widget>[
            SliverStaggeredGrid.countBuilder(
              crossAxisCount: 2,
              itemBuilder: (context, index) {
                DocumentSnapshot documentSnapshot =
                    snapshot.data.documents[index];
                return _gridItem(documentSnapshot);
              },
              staggeredTileBuilder: (int index) => const StaggeredTile.fit(1),
              itemCount: snapshot.data.documents.length,
            ),
          ],
        );
      },
    );
  }

一つ一つ説明していきます。 このプロジェクトではFirebaseのCloud Firestoreからデータを取得して画面に表示しているので StreamBuilder を使用しています。

 return CustomScrollView(

この部分で CustomScrollView でラップしているのは多分内部でSliver~~~のメソッドを使用しているためだと思います。 これがないとクラッシュするので必ずこれをルートに指定しましょう。

SliverStaggeredGrid.countBuilder

このソースコードでは SliverStaggeredGrid.countBuilder を使用してますが、ここは GridView の使い方と同じで状況によって使い分けましょう。 GridViewでいうところの delegate の中の実装と同じです。

staggeredTileBuilder: (int index) => const StaggeredTile.fit(1), 属性を使用していますが、ここもいろいろなメソッドが用意されています。

ここはReadMeにちゃんと書かれています。

A StaggeredGridView needs to know how to display each tile, and what widget is associated with a tile.

A tile needs to have a fixed number of cell to occupy in the cross axis. For the extent in the main axis you have 3 options:

・You want a fixed number of cells => use StaggeredTile.count.
・You want a fixed extent => use StaggeredTile.extent.
・You want a variable extent, defined by the content of the tile itself => use StaggeredTile.fit.

状況によって使い分けましょう。

これを使う状況

個人的にこれを使うべき場所はいろいろあると思いますが、 一つのアイテムの要素が一つ以上の場合 とかに使うべきかなと思います。