リファレンス
Reference

横並びで均等に要素を並べる

URLをコピーする Twitterでシェアする Facebookでシェアする

RowExpanded を使って、横並びで均等にかつレスポンシブに要素を並べてみます。

横方向に要素を並べる

Row は横方向に要素を並べるための Widget です。

children に並べたい要素を配列として要素を入れていきます。

このトピックでは、赤、青、緑の 3 個の Container が入ってる Row の例を使って解説を進めていきます。

Container を並べる

まずは Row に 3 つの Container を入れていきましょう。

MainAxisAlignment.spaceEvenly は、子要素を横方向に均等に配置する設定です。(詳細はこちら)

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Container(color: Colors.red),
    Container(color: Colors.blue),
    Container(color: Colors.green),
  ],
)

実は、このように Containerheightwidth を指定せずに書いたら、下の画面のように何も表示されません。

heightwidth を指定すれば、3 種類の Container が表示されるようになります。

Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Container(
      color: Colors.red,
      height: 80,  // サイズ指定しないと表示されない
      width: 80,
    ),
    Container(
      color: Colors.blue,
      height: 80,
      width: 80,
    ),
    Container(
      color: Colors.green,
      height: 80,
      width: 80,
    ),
  ],
),

サイズをレスポンシブに表示する

ユーザーが使用するデバイスの画面サイズはそれぞれ異なるので、すべての画面サイズに対応したアプリを作るのに、 Expanded は必要不可欠な存在です。

例えば、親 Widget の横幅がデバイスのサイズによって縮小された場合、前節のコードのままでアプリを起動すると、どうなるでしょうか。

答えは、以下のように親 Widget の右側に RenderFlex Overflowed エラーが検出されます。

このエラーメッセージは、指定された子要素の横幅は親 Widget の横幅を越えていることを意味しています。

height = 80 のようにサイズをハードコーディングをすると、上記のようなエラーに遭遇するユーザーがいるかもしれません。それによって、ユーザーフレンドリーではないアプリと認識されて、ユーザー離れに繋がるので気をつけましょう。

異なるサイズのデバイスに対応するためには、 Expanded を使いましょう。

Expanded は、子要素のサイズを親 Widget のサイズに対してレスポンシブに変化させます。

使い方もとても簡単で、レスポンシブにしたい子要素を包むだけです。

例えば、赤の ContainerExpanded で包み、

Row(
  children: [
    Expanded(
      child: Container(
        color: Colors.red,
        height: 80,
        width: 80,  // 指定されても、Expanded に包まれると無視される
      ),
    ),
    Container(
      color: Colors.blue,
      height: 80,
      width: 80,  // キープされる
    ),
    Container(
      color: Colors.green,
      height: 80,
      width: 80,  // キープされる
    ),
  ],
),

のように書くと、どうなるでしょうか。

その結果は、赤の Containerwidth に設定された値が無視されて、赤の Container は取れるだけの横幅を持つようになります。

青と緑の ContainerExpanded に包まれてないので、それらの width は 80 ピクセルのまま表示されます。

次に、残りの青と緑の ContainerExpanded で包むと、3 つの Container が均等に配置されるようになります。

Row(
  children: [
    Expanded(
      child: Container(
        color: Colors.red,
        height: 80,
        width: 80,  // 指定されても、Expanded に包まれると無視される
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.blue,
        height: 80,
        width: 80,  // 指定されても、Expanded に包まれると無視される
      ),
    ),
    Expanded(
      child: Container(
        color: Colors.green,
        height: 80,
        width: 80,  // 指定されても、Expanded に包まれると無視される
      ),
    ),
  ],
),

親 Widget である Row の中に、左右の空白や子要素の間隔もレスポンシブに作ることができます。

Expandedchild を空の状態で起動するとエラーが出てしまいます。

そこで、小要素の child が必要のない空の Expanded 、とも言える便利な Widget Spacer を使うと、レスポンシブな空白を簡単に実装できます。

それでは、Spacer を使ってレスポンシブな空白を入れていきましょう。

Row(
  children: [
    Spacer(),  // レスポンシブな空白
    Expanded(
      child: Container(
        color: Colors.red,
        height: 80,
        width: 80,
      ),
    ),
    Spacer(),  // レスポンシブな空白
    Expanded(
      child: Container(
        color: Colors.blue,
        height: 80,
        width: 80,
      ),
    ),
    Spacer(),  // レスポンシブな空白
    Expanded(
      child: Container(
        color: Colors.green,
        height: 80,
        width: 80,
      ),
    ),
    Spacer(),  // レスポンシブな空白
  ],
),

これで、親 Widget の幅が小さくなっても、子要素はそれに合わせてレスポンシブに変化するようになりました。

そして、以前に表示されていた RenderFlex Overflowed エラーが解消されました。

Flex を使って子要素のサイズ配分を調節する

また、ExpandedSpacerflex というプロパティを追加すると、flexに指定する値分だけ、要素のサイズを確保してくれます。

flex: 3 と指定すると、要素3つ分のスペースを確保してくれます。

例えば、 赤、青、緑の Container に、それぞれ flex: 1flex: 2flex: 3 を設定すると、 下の画像のように、3 つの Container が横幅 1 : 2 : 3 で配分されるようになります。

Row(
  children: [
    Expanded(
      flex: 1, // 1 要素分の横幅
      child: Container(
        color: Colors.red,
        height: 80,
        width: 80,
      ),
    ),
    Expanded(
      flex: 2, // 2 要素分の横幅 
      child: Container(
        color: Colors.blue,
        height: 80,
        width: 80,
      ),
    ),
    Expanded(
      flex: 3, // 3 要素分の横幅 
      child: Container(
        color: Colors.green,
        height: 80,
        width: 80,
      ),
    ),
  ],
),

今回は Row での Expandedの使い方を説明しました。 Column においても、ほぼ同じ方法で使用できます。 ただし、Row では width がレスポンシブ対応されるのに対して、Column では height がレスポンシブ対応されます。

参考リンク