主题
布局约束
规则
- 上层 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
的大小以使其也适合屏幕