🥅

【Flutter】グリッドの背景を作成する

2023/06/14に公開

どういうことか

こういうものを作りたい。
画面いっぱいに方眼紙のようなグリッド(Grid)が広がっている。

コード

Widget gridBackGround() {
    return Container(
      // 背景色の設定部分
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Colors.black,
            Colors.purple,
            Colors.pink,
          ],
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
        ),
      ),
      // グリッドの設定部分
      child: LayoutBuilder(
        builder: (context, constraints) {
          const double gridSize = 30.0; // 1マスのサイズ
          final int numColumns = (constraints.maxWidth / gridSize).ceil();
          final int numRows = (constraints.maxHeight / gridSize).ceil();
          return GridView.builder(
            padding: EdgeInsets.zero,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: numColumns,
            ),
            itemCount: numColumns * numRows,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                decoration: BoxDecoration(
                  border: Border.all(
                    color: Colors.white.withOpacity(0.3), // 線の色
                    width: 0.5, // 線の太さ
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }

解説

切り分けて説明していく。

背景色の設定

ここで背景色としてグラデーションを設定している(80年代を意識した)。
もちろんグラデーションをかけないとグリッドが表示されないわけではない。
この部分をまるっと削除すると背景が真っ白になる。

      // 背景色の設定部分
      decoration: const BoxDecoration(
        gradient: LinearGradient(
          colors: [
            Colors.black,
            Colors.purple,
            Colors.pink,
          ],
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
        ),
      ),

グリッドの設定

グリッドは以下で設定している。

      // グリッドの設定部分
      child: LayoutBuilder(
        builder: (context, constraints) {
          const double gridSize = 30.0; // 1マスのサイズ
          final int numColumns = (constraints.maxWidth / gridSize).ceil();
          final int numRows = (constraints.maxHeight / gridSize).ceil();
          return GridView.builder(
            padding: EdgeInsets.zero,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: numColumns,
            ),
            itemCount: numColumns * numRows,
            itemBuilder: (BuildContext context, int index) {
              return Container(
                decoration: BoxDecoration(
                  border: Border.all(
                    color: Colors.white.withOpacity(0.3), // 線の色
                    width: 0.5, // 線の太さ
                  ),
                ),
              );
            },
          );
        },
      ),

まず constrains で親ウィジェットの制約情報を取得している。
以下では縦横のセルの数を計算して各変数を定義する。親ウィジェットの最大幅を gridSize 、ここで言うと30で割り、切り上げ処理を行っている。

final int numColumns = (constraints.maxWidth / gridSize).ceil();
final int numRows = (constraints.maxHeight / gridSize).ceil();

GridView.builder でグリッドビューを作成する。
padding はナシで設定する。
設定するとグリッド全体の外側に空白ができる。デザインによっては設定したい。

padding: EdgeInsets.zero,

gridDelegate でグリッドのレイアウト方法を指定する。 SliverGridDelegateWithFixedCrossAxisCount で横方向のセル数をで numColumns を使って指定する。

gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  crossAxisCount: numColumns,
),

itemCount でグリッド内のセルの総数を指定する。横方向のセルの数と縦方向のセルの数をかけた数を指定する。

itemCount: numColumns * numRows,

itemBuilder では、各セルのウィジェットを構築する。ここでは、単純な白い枠線を持つコンテナを設定し、 decoration している。

itemBuilder: (BuildContext context, int index) {
  return Container(
    decoration: BoxDecoration(
      border: Border.all(
        color: Colors.white.withOpacity(0.3), // 線の色
        width: 0.5, // 線の太さ
      ),
    ),
  );
},

以上です。
あとは80sのロゴや画像を載せて仕上げる😪

return Stack(
  children: [
    gridBackGround(),
    Image.asset("assets/80s_logo.png"),
  ],
);

Arsaga Developers Blog

Discussion