Flutterレイアウトシリーズのその他の記事
- Stackの使い方
- FlutterレイアウトのOverlayの使用
- Flutterのレイアウトを理解する
- FlutterレイアウトのExpanded、Flexible、Spacer
- FlutterレイアウトのFlex、Row、Column、Wrap、Stackについて
この記事はFlutterのBoxConstraintsを理解するため書いたものです。
※本記事は下記のZenn本にまとめました。
BoxConstraintsとは
Flutter開発の中、多少遭遇したことあると思いますが、画面が設定したサイズ通りに描画してくれません。( 例1)それはBoxConstraintsのせいだから、BoxConstraintsに文言を言いたい一方で、そのおかげで、Flutter開発の中多くのものはサイズを定義しなくて、簡単に画面描画できました。
BoxConstraintsはFlutterのサイズ制約ロジックです。親から子へ渡される、幅の最大値・最小値と高さの最大値・最小値のことです。 あるWidgetは親に決められた最小値と最大値の間で、自身のSizeを決めることになります。
例1:幅100,高さ30の青色のボックスを作りたいですが、画面全体が青色になってしまった!!!
return SizedBox(
width: 100,
height: 30,
child: Container(
color: Colors.blue,
),
);
BoxConstraintsのtightコンストラクター
上記の現象起こる理由はBoxConstraintsのコンストラクターです。幅と高さの最小値・最大値はsizeのwidthとheightです。要は使えるサイズは1つしかないです。
BoxConstraints.tight(Size size)
: minWidth = size.width,
maxWidth = size.width,
minHeight = size.height,
maxHeight = size.height;
例1のUIをDevToolsのUI Tree(下図)で確認しましょう。サイズが幅375、高さ667になっていることが分かりました。それは端末のサイズです。
親から継承した制約で、子はSizedBoxのみで制約突破は不可です。ですので、サイズを変更することは不可能です。
BoxConstraintsの制約突破
- UnconstrainedBox
下記のコードのように、上述のUIコードにUnconstrainedBoxを追加することで、BoxConstraintsの制約突破することできました。UIはコードの下部で貼り付けます。
return UnconstrainedBox(
child: SizedBox(
width: 100,
height: 30,
child: Container(
color: Colors.blue,
),
),
);
では、DevToolsのUIツリーでサイズを確認しましょう。SizedBoxは親のUnconstrainedから制約を継承し、Unconstrainedになっており、自由定義することができました。Boxconstraintsのサイズが定義して通りになっていることが分かりました。
2. Align、Flex、Column、Row、Wrap、Stack
AlignなどのWigetで制約を突破することもできます。
return Align(
child: SizedBox(
width: 100,
height: 30,
child: Container(
color: Colors.blue,
),
),
);
- 制約のカスタマイズ
SingleChildLayoutDelegateを継承し、CustomSingleChildLayoutを使うことで、BoxConstraintsのカスタマイズもできます。
...
return CustomSingleChildLayout(
delegate: CustomizeLayoutDelegate(),
child: Container(
color: Colors.blue,
),
);
...
class CustomizeLayoutDelegate extends SingleChildLayoutDelegate {
@override
bool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate) => false;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints.tight(const Size(100, 100));
}
}
まとめ
BoxConstraints.tigh()の制約を突破する方法は3つあります。
- UnconstrainedBoxによる制約解除
- Align、Flex、Column、Row、Wrap、StackなどWidgetによる制約解除
- CustomSingleChildLayoutによる制約解除
補足
ScaffoldはWidgetの集合体であり、ScaffoldはBoxConstraints制約を突破できる理由はCustomMultiChildLayoutを使って突破しているからです。