すらぼうの開発ノート

モバイルアプリエンジニアのメモ

【Flutter】Constraints(制約)について

FlutterはUIを作成する際にConstraintsという情報を扱っている。 そのConstraintsを説明した記事が公式から出ている。

docs.flutter.dev

このポストでは上の記事を読んで、個人的にメモに残したい内容を記載する。

Constraintsはウィジェットのサイズと位置を決めるもの

Constraints go down. Sizes go up. Parent sets position.

UIが生成される際には以下の登場人物が現れる。

登場人物名 説明
Constraints Sizeの制約。最大幅、最小幅、最大高さ、最小高さの4変数。
Size ウィジェットの大きさ
Position 親の範囲内での子の表示位置

そして位置とサイズが決まるフローは

  1. 親がConstraintsを子に伝える
  2. 子が希望のSizeを伝え、親がConstraintsを基に子のSizeを決める
  3. 親がSizeを基にPositionも決める
  4. 3によって親のSizeも決まる

SizeとPositionは総合的に決まる

Flutter’s layout engine is designed to be a one-pass process. This means that Flutter lays out its widgets very efficiently, but does result in a few limitations:

A widget can decide its own size only within the constraints given to it by its parent. This means a widget usually can’t have any size it wants.

A widget can’t know and doesn’t decide its own position in the screen, since it’s the widget’s parent who decides the position of the widget.

Since the parent’s size and position, in its turn, also depends on its own parent, it’s impossible to precisely define the size and position of any widget without taking into consideration the tree as a whole.

If a child wants a different size from its parent and the parent doesn’t have enough information to align it, then the child’s size might be ignored. Be specific when defining alignment.

子は希望Sizeは必ず実現できるわけではない。親から渡されたConstraints、他の子との相互作用などの要素が絡んで総合的に決まる。

ウィジェットごとにConstraintsへの対応が異なる

In Flutter, widgets are rendered by their underlying RenderBox objects. Many boxes in Flutter, especially those that just take a single child, pass their constraint on to their children.

  • 極力大きくなるもの
  • 極力子のSizeに合わせるもの
  • 特定のサイズを維持しようとするもの
  • 状況によって複雑に変わるもの
    • Container、Row、Column

画面サイズは強制的

For an interactive experience, use the following DartPad. Use the numbered horizontal scrolling bar to switch between 29 different examples.

ウィジェットツリーのトップのウィジェットは、Sizeが画面サイズに強制的に合わせられる。これをAppウィジェットがタイトなConstraintsを持っているため。

もしサイズを任意で変更したければルーズなConstraintsを持たせるか、最小〜最大に幅のあるウィジェットをツリーに挿入する。