17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutterレイアウト】BoxConstraintsを理解する

Last updated at Posted at 2022-04-18

Flutterレイアウトシリーズのその他の記事

この記事は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の制約突破

  1. 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,
        ),
      ),
    );
  1. 制約のカスタマイズ
    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つあります。

  1. UnconstrainedBoxによる制約解除
  2. Align、Flex、Column、Row、Wrap、StackなどWidgetによる制約解除
  3. CustomSingleChildLayoutによる制約解除

補足

ScaffoldはWidgetの集合体であり、ScaffoldはBoxConstraints制約を突破できる理由はCustomMultiChildLayoutを使って突破しているからです。

17
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?