ConstrainedBoxBoxConstraints を使うことで要素の大きさを制限します。

ConstrainedBoxとは

ConstrainedBox は、 BoxConstraints と組み合わせて使うことによって、包まれる子要素の大きさを制限します。

画面の大きさは機種ごとに違うので、限られた端末の画面内に要素を収めるために非常に重要な要素です。

使い方

ConstrainedBox は、引数 constraintsBoxConstraints を指定して使います。

ConstrainedBox(
  constraints: BoxConstraints(maxWidth: 320.0, maxHeight: 64.0),
  child: Container(
    color: Colors.red,
  ),
)

のように書きます。引数 child には、表示したい要素を指定します。

また、 BoxConstraints の引数には、 minWidthminHeightmaxWidthmaxHeight の 4 つの引数を任意に入れることができます。

BoxConstraints に何も引数を指定しない場合、 minWidthminHeight0.0maxWidthmaxHeightdouble.infinity (無限大) と指定されます。 この場合、中の要素によって大きさが左右されるため、 ConstrainedBox を使っても使わなくても結果は変わりません。 そのため、 BoxConstraints を使う場合には、引数に必ず 1 つ以上指定しましょう。

応用例

ここで、画面の横幅に合わせてサイズが変化するボタンを例にしましょう。

以下のコードでは、width が画面の横幅の 60% となるようなボタンが 2 つ作られています。

唯一の違いは、下のボタンは横幅が 300px を超えない ConstrainedBox に包まれています。

// デバイスの横幅を取得する
double screenWidth = MediaQuery.of(context).size.width; 

Column(
  children: [
    SizedBox( // ボタンのサイズは親の SizedBox/Container のサイズに依存する
      width: screenWidth * 0.6, //横幅を画面サイズの 60% にする
      child: ElevatedButton(
        child: Text('Happy Flutter'),
        onPressed: (){},
      ),
    ),
    ConstrainedBox(
      // 横幅は最大 300px までしか自由に伸長できない制限をかける
      constraints: BoxConstraints(maxWidth: 300),
      child: SizedBox(
        width: screenWidth * 0.6,
        child: ElevatedButton(
          child: Text('Happy Flutter'),
          onPressed: (){},
        ),
      ),
    ),
  ],
)

iPhone を縦向きに使う時に、2 つのボタンは全く同じに見えますよね。

では、iPhone を横向きにすると、2 つのボタンの width はどのように変化するでしょうか。

iPhone の向きによって横幅と縦幅は入れ替わるため、2 つのボタンの width も横向き時の横幅に合わせて変化します。

その結果は、ConstrainedBox に包まれてないボタンの横幅が長くなり、 ConstrainedBox に包まれたボタンは丁度いい横幅に収まりました。

ConstrainedBox に包まれてないボタンは、確かに画面横幅の 60% となるように正しく変化してくれましたが、ボタンにしては横幅が長すぎると思いませんか。

一方で、ConstrainedBox に包まれたボタンは、 ConstrainedBox によって横幅が最大 300px までしか伸長できない制限がかけられているのが分かります。

まとめ

ConstrainedBox は Widget が不自然な大きさへ伸長しないように制限をかけることができます。

同様に、 Widget が潰れないよう、必要最低限のサイズを確保することもできます。

まとめると、レスポンシブデザインにサイズの上限値または下限値を設定したい時に便利な要素です。

参考リンク