主题
布局约束
规则
- 上层 widget 向下层 widget 传递约束条件
- 下层 widget 向上层 widget 传递大小信息
- 最后,上层 widget 决定下层 widget 的位置
严格约束和宽松约束
严格约束
严格约束是确切的大小,即它的最大/最小宽高是一致的
dart
BoxConstraints.tight(Size size)
: minWidth = size.width,
maxWidth = size.width,
minHeight = size.height,
maxHeight = size.height;宽松约束
宽松约束设置了最大宽度/高度,但是让允许其子 widget 获得比它更小的任意大小
dart
BoxConstraints.loose(Size size)
: minWidth = 0.0,
maxWidth = size.width,
minHeight = 0.0,
maxHeight = size.height;样例 1

dart
Container(width: 100, height: 100, color: red)屏幕就是严格约束,会强制子变成和屏幕一样的大小。
虽然红色的 Container 想要变成 100 x 100 的大小,但是它无法变成,因为屏幕强制它变成和屏幕一样的大小
样例 2

dart
Center(
child: Container(width: 100, height: 100, color: red),
)Center 就是宽松约束
屏幕强制 Center 变得和屏幕一样大,所以 Center 充满了屏幕
然后 Center 告诉 Container 可以变成任意大小,但是不能超出屏幕。所以Container 可以真正变成 100 × 100 大小
样例 3

dart
Align(
alignment: Alignment.bottomRight,
child: Container(width: 100, height: 100, color: red),
)Align 同样也告诉 Container,你可以变成任意大小,但是不能超出屏幕。所以Container 也变成 100 × 100 大小
样例 4
若 Container 的父组件为宽松约束,Constainer 没有子组件,则它有多大就多大

dart
Center(
child: Container(color: red),
)屏幕强制 Center 变得和屏幕一样大,所以 Center 充满屏幕
然后 Center 告诉 Container 可以变成任意大小,但是不能超出屏幕。由于 Container 没有子级而且没有固定大小,所以它决定能有多大就有多大,所以它充满了整个屏幕
样例 5
若 Container 的父组件为宽松约束,Constainer 有子组件,则它会变成它子组件的大小

dart
Center(
child: Container(
color: red,
child: Container(color: green, width: 30, height: 30),
),
)屏幕强制 Center 变得和屏幕一样大,所以 Center 充满屏幕
然后 Center 告诉红色的 Container 可以变成任意大小,但是不能超出屏幕。由于 Container 没有固定大小但是有子级,所以它决定变成它 child 的大小
然后红色的 Container 告诉它的 child 可以变成任意大小,但是不能超出屏幕
而它的 child 是一个想要 30 × 30 大小绿色的 Container。由于红色的 Container 和其子级一样大,所以也变为 30 × 30。由于绿色的 Container 完全覆盖了红色 Container,所以你看不见它了
ConstrainedBox
ConstrainedBox 可约束 4 个浮点类型的集合:最大/最小宽度,以及最大/最小高度
ConstrainedBox 会优先遵从它父级的约束,而后再根据接收到的约束,约束它的子级
样例 1

dart
ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: red, width: 10, height: 10),
)屏幕迫使 ConstrainedBox 与屏幕大小完全相同,因此它告诉其子 Widget 也以屏幕大小作为约束,从而忽略了其 constraints 参数带来的影响
样例 2

dart
Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: red, width: 10, height: 10),
),
)Center 允许 ConstrainedBox 达到屏幕可允许的任意大小。 ConstrainedBox 将 constraints 参数带来的约束附加到其子对象上
Container 必须介于 70 到 150 像素之间。虽然它希望自己有 10 个像素大小,但最终获得了 70 个像素(最小为 70)
UnconstrainedBox
UnconstrainedBox 会可以让子级是任意大小
UnconstrainedBox 本身还是受到父级约束的
样例 1

dart
UnconstrainedBox(
child: Container(color: red, width: 20, height: 50),
)屏幕强制 UnconstrainedBox 变得和屏幕一样大,而 UnconstrainedBox 允许其子级的 Container 可以变为任意大小
样例 2

dart
UnconstrainedBox(
child: Container(color: red, width: 4000, height: 50),
)屏幕强制 UnconstrainedBox 变得和屏幕一样大,而 UnconstrainedBox 允许其子级的 Container 可以变为任意大小
但子容器太大了,无法容纳在 UnconstrainedBox 中,因此 UnconstrainedBox 将显示溢出警告
样例 3

dart
OverflowBox(
minWidth: 0.0,
minHeight: 0.0,
maxWidth: double.infinity,
maxHeight: double.infinity,
child: Container(color: red, width: 4000, height: 50),
)OverflowBox 与 UnconstrainedBox 类似,但不同的是,如果其子级超出该空间,它将不会显示任何警告
样例 4

dart
UnconstrainedBox(
child: Container(color: Colors.red, width: double.infinity, height: 100),
)这将不会渲染任何东西,而且你能在控制台看到错误信息
UnconstrainedBox 让它的子级决定成为任何大小,但是其子级是一个具有无限大小的 Container
Flutter 无法渲染无限大的东西,所以它抛出以下错误: BoxConstraints forces an infinite width.(盒子约束强制使用了无限的宽度)
适应性布局
样例 1

dart
const FittedBox(
child: Text('Some Example Text.'),
)屏幕强制 FittedBox 变得和屏幕一样大,而 Text 则是有一个自然宽度(也被称作 intrinsic 宽度),它取决于文本数量,字体大小等因素
FittedBox 让 Text 可以变为任意大小。但是在 Text 告诉 FittedBox 其大小后, FittedBox 缩放文本直到填满所有可用宽度
样例 2

dart
const Center(
child: FittedBox(
child: Text('Some Example Text.'),
),
)Center 将会让 FittedBox 能够变为任意大小,取决于屏幕大小
FittedBox 然后会根据 Text 调整自己的大小,然后让 Text 可以变为所需的任意大小,由于二者具有同一大小,因此不会发生缩放
样例 3

dart
const Center(
child: FittedBox(
child: Text(
'This is some very very very large text that is too big to fit a regular screen in a single line.'),
),
)FittedBox 会尝试根据 Text 大小调整大小,但不能大于屏幕大小。然后假定屏幕大小,并调整 Text 的大小以使其也适合屏幕
