Flutter基礎 – Column/Rowの色々な並べ方

【そのまま並べる

(左)Column、(右)Row
※グレーの部分は分かりやすいようにそれぞれColumn、Rowを着色したもの

💡POINT💡

  • どちらも原点は”左上
  • デフォルトでColumnは”縦方向いっぱい”、Rowは”横方向いっぱい”のサイズになる。
class PatternSimple extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('タイトル'),
      ),
      body: Container(
        color: Colors.grey,
        child: Column(
          children: <Widget>[
            Container(
              color: Colors.brown,
              height: 50.0,
              width: 100.0,
            ),
            Container(
              color: Colors.green,
              height: 50.0,
              width: 100.0,
            ),
            Container(
              color: Colors.amber,
              height: 50.0,
              width: 100.0,
            ),
          ],
        ),
      ),
    );
  }
}

【ウィジェットの中央寄せ(Centerウィジェット)

[左)Column、(右)Row

💡POINT💡

  • Centerウィジェットで中央に寄るのはColmn(Row)自体
  • 内部コンテンツの位置は変わらない。
// 省略
      body: Center(
        child: Container(
          color: Colors.grey,
          child: Row(
            children: <Widget>[
              Container(
                color: Colors.brown,
                height: 50.0,
                width: 100.0,
              ),
              Container(
                color: Colors.green,
                height: 50.0,
                width: 100.0,
              ),
              Container(
                color: Colors.amber,
                height: 50.0,
                width: 100.0,
              ),
            ],
          ),
        ),
      ),
// 省略

【主軸方向の位置調整

先頭/末尾寄せ – MainAxisAlignment.start/end

MainAxisAlignment.start
MainAxisAlignment.end

💡POINT💡

  • 先頭”とはColumnの場合上端、Rowの場合左端を表す
  • 末尾”とはColumnの場合下端、Rowの場合右端を表す
// 省略
          child: Column(

            // 先頭寄せ
            mainAxisAlignment: MainAxisAlignment.start,

            // 末尾寄せ
            // mainAxisAlignment: MainAxisAlignment.end,

            children: <Widget>[
// 省略

中央寄せ – MainAxisAlignment.center

MainAxisAlignment.center

💡POINT💡

  • Column(Row)の主軸方向にコンテンツを配置するのがmainAxisAlignment引数。
  • centerは主軸方向に中央寄せ
  • ここで初めて、コンテンツの中央寄せができる
// 省略
          child: Column(

            // 中央寄せ
            mainAxisAlignment: MainAxisAlignment.center,

            children: <Widget>[
// 省略

間隔を均等に配置 – MainAxisAlignment.spaceEvenly

MainAxisAlignment.spaceEvenly

(”間隔を均等に”という表現が適当なのかは少し不安😅)

💡POINT💡

  • コンテンツを主軸方向に広げる。
  • 先頭と末尾の余白”、”コンテンツ同士の間隔”がすべて均等
// 省略
          child: Column(

            // 間隔を均等に配置
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,

            children: <Widget>[
// 省略

余白を均等に配置 – MainAxisAlignment.spaceAround

MainAxisAlignment.spaceAround

(上に同じく”余白を均等に”という表現が適当なのかは少し不安😅)

💡POINT💡

  • コンテンツを主軸方向に広げる。
  • 各コンテンツの主軸方向のmargin”が均等というイメージ。
  • 結果的に「(先頭と末尾の余白) = 1 / (コンテンツ同士の間隔)」となる。
// 省略
          child: Column(

            // 余白を均等に配置
            mainAxisAlignment: MainAxisAlignment.spaceAround,

            children: <Widget>[
// 省略

分散させて配置 – MainAxisAlignment.spaceBetween

MainAxisAlignment.spaceBetween

💡POINT💡

  • コンテンツを主軸方向に広げる。
  • 各コンテンツそれぞれを”限界まで遠ざける”イメージ。
  • 先端、後端のコンテンツは端に移動する
// 省略
          child: Column(

            // 分散させて配置
            mainAxisAlignment: MainAxisAlignment.spaceBetween,

            children: <Widget>[
// 省略

【交差軸方向の位置調整

先頭/末尾寄せ – CrossAxisAlignment.start/end

CrossAxisAlignment.start
CrossAxisAlignment.end

※主軸方向の位置はMainAxisAlignment.spaceAroundに指定

💡POINT💡

  • コンテンツをそれぞれ交差軸方向の先頭、末尾に寄せる
  • ”交差軸”とは、Columnなら”横方向”Rowなら”縦方向”を表す。(主軸と”交差”する方向)
// 省略

      body: Center(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 32.0),
          child: Container(
            // 交差軸方向に移動するためのスペースを開ける
            width: double.infinity,
            height: double.infinity,
            color: Colors.grey,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,

              // 交差軸方向の先頭寄せ
              crossAxisAlignment: CrossAxisAlignment.start,

              // 交差軸方向の末尾寄せ
              // crossAxisAlignment: CrossAxisAlignment.end,

              children: <Widget>[
                Container(
                  color: Colors.brown,
                  height: 50.0,
                  width: 100.0,
                ),
                Container(
                  color: Colors.green,
                  height: 50.0,
                  width: 100.0,
                ),
                Container(
                  color: Colors.amber,
                  height: 50.0,
                  width: 100.0,
                ),
              ],
            ),
          ),
        ),
      ),

// 省略

中央寄せ – CrossAxisAlignment.center

CrossAxisAlignment.center

💡POINT💡

  • コンテンツを交差軸方向の中央に寄せる
// 省略
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,

              // 交差軸方向の中央寄せ
              crossAxisAlignment: CrossAxisAlignment.center,

              children: <Widget>[
// 省略

引き伸ばして配置 – CrossAxisAlignment.stretch

CrossAxisAlignment.stretch

💡POINT💡

  • コンテンツを交差軸方向に引き伸ばして配置する。
  • 各コンテンツの交差軸方向のサイズ指定は無視される。
// 省略
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,

              // 交差軸方向に引き伸ばして配置
              crossAxisAlignment: CrossAxisAlignment.stretch,

              children: <Widget>[
// 省略

ベースラインを揃えて配置 – CrossAxisAlignment.baseline

(左)無指定、(右)CrossAxisAlignment.baseline

※ここでは主軸方向の位置指定はしていない。

💡POINT💡

  • コンテンツのベースラインを揃えて配置する。
  • Rowの場合上図のようになるが、Columnの場合CrossAxisAlignment.startと同じ働きをする(ベースラインは常に”水平”なため)
  • ベースラインの指定をしないとエラーになるので注意
// 省略
      body: Center(
        child: Container(
          color: Colors.grey,
          child: Row(

            // (1) ベースラインに揃えて配置
            crossAxisAlignment: CrossAxisAlignment.baseline,

            // (2) ベースラインの指定
            textBaseline: TextBaseline.alphabetic,

            children: <Widget>[
              Text(
                'AAA',
                style: TextStyle(fontSize: 100.0),
              ),
              Text(
                'BBB',
                style: TextStyle(fontSize: 40.0, color: Colors.tealAccent),
              ),
            ],
          ),
        ),
      ),
// 省略

【ColumnとRowの組み合わせ

Columnの中にRowを配置

(オレンジ部分)Column
(イエロー部分)Row
(ブルー部分)コンテンツ

💡POINT💡

  • Columnの子ウィジェットとして、Rowを3つ配置。
  • 各Rowの子ウィジェットとして、正方形のContainerを配置。
// 省略

      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[

          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),

          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),

          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),

        ],
      ),

// 省略

Rowの中にColumnを配置

(オレンジ部分)Column
(イエロー部分)Row
(ブルー部分)コンテンツ

💡POINT💡

  • Rowの子ウィジェットとして、Columnを3つ配置。
  • 各Columnの子ウィジェットとして、正方形のContainerを配置。
      body: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
              Container(
                color: Colors.blue,
                height: 100.0,
                width: 100.0,
              ),
            ],
          ),
        ],
      ),