Container
一个集绘制、定位和大小调整于一体的容器组件
Container首先会用padding将内部子组件包裹起来,如果在decoration中设置了边框,那么padding还将算上边框。之后如果height或者width不为空的话,还将对内部范围添加额外根据height或者width设定的约束。最后根据margin设置的大小给Container外部包裹对应大小的外边框。
在绘制过程中,Container会先应用给定的变化,然后根据decoration中的设置去绘制装饰层填充范围。再然后就会去绘制子组件,最后根据foregroundDecoration绘制前景装饰层填充范围。
在没有子组件的时候,Container会尽量撑满空间,除非遇到了无限宽高限制的情况-这时候它就会反过来尽量缩小。而内部有子组件的Container则会根据子组件的大小进行自适应。但是如果构造器里如果传入了width、height和constraints参数,都将覆盖自身的这些默认行为。
一般情况下,Container是不会响应点击事件的(它永远返回false)。在设置了color属性的情况下,点击就会交由ColoredBox进行处理(它永远返回true)。要是设置了decoration或者foregroundDecoration属性,那么就会交由Decoration.hitTest方法来进行响应处理。
布局行为
因为Container集成了很多其他自带布局功能的Widget,所以它的布局行为非常的复杂!
总的来说,Container布局策略是按照如下优先级来的:
- 进行对齐
- 根据子组件调整尺寸
- 根据宽高和
constraints限制进行调整 - 撑满父组件
- 尽可能缩小自己
对应的具体操作就是:
- 如果
Container没有子组件,也没有设置宽高,也没有约束条件,父组件也没有给约束限制,这时候Container就会尽可能将自己缩小 - 如果
Container没有子组件,也没有设置对齐方式,但是指定了宽高或者constraints,这时候Container就会在自身约束和父级约束的共同作用下,将自己缩到最小 - 如果
Container没有子组件,没有对齐方式,没有高度宽度自身约束,但是父组件设置了约束的话,那么Container会根据父组件设置的约束来撑满自己 - 如果
Container设置了对齐方式,而父组件给了无限制约束的话,那么Container会主动调整自己的尺寸去包裹住子组件 - 如果
Container设置了对齐方式,而父组件给了固定约束的话,那么Container会先撑满自己,再按照对齐方式去调整子组件在Container中的位置 - 如果
Container没有设置尺寸,约束和对齐方式,但是有子组件,那么Container就会把父组件的约束条件给子组件,自己的大小跟着子组件来自适应 margin和padding也会影响布局效果,它们的作用就是辅助上面那些规则。decoration设置可能会偷偷加大padding(比如BoxDecoration的边框会占据padding的空间)
更多关于盒子布局模型的内容,可以参看BoxConstraints的文档。
例子
例子A
Center(
child: Container(
margin: const EdgeInsets.all(10.0),
color: Colors.amber[600],
width: 48.0,
height: 48.0,
),
)
按照上面的规则,Container没有子组件也没有设置对齐方式,但是设置了宽高,Center没有设置宽高,则Center给Container的约束变为松约束(0<=w<=屏幕宽度,0<=h<=屏幕高度),那么Container将会遵守自身宽高约束变为48 * 48的琥珀色方块,然后再设置了10外边距,再因为外部包裹了Center组件,Container会处于父组件的中间。

例子B
Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.headlineMedium!.fontSize! * 1.1 + 200.0,
),
padding: const EdgeInsets.all(8.0),
color: Colors.blue[600],
alignment: Alignment.center,
transform: Matrix4.rotationZ(0.1),
child: Text('Hello World',
style: Theme.of(context)
.textTheme
.headlineMedium!
.copyWith(color: Colors.white)),
)
Container使用了BoxConstraints.expand且没有设置width,那么width会扩展到外部最大的宽度(通常为屏幕宽度),height则设置为中号标题字体大小的1.1倍加上200。设置内边距为8,颜色为蓝色,并围绕Z轴进行旋转。设置对齐方式为居中对齐,这样子组件就被放置在Container的中间,然后渲染一个Text子组件,设置内容和样式。

构造函数
Container.new({
Key? key,
AlignmentGeometry? alignment,
EdgeInsetsGeometry? padding,
Color? color,
Decoration? decoration,
Decoration? foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
EdgeInsetsGeometry? margin,
Matrix4? transform,
AlignmentGeometry? transformAlignment,
Widget? child,
Clip clipBehavior = Clip.none
})
参数
| 参数名 | 参数类型 | 解释 |
|---|---|---|
| alignment | AlignmentGeometry | 在Container内放置child的对齐方式 |
| child | Widget? | Container的子组件 |
| clipBehavior | Clip | Container的裁剪行为 |
| color | Color? | Container填充的颜色 |
| constraints | BoxConstraints? | 对于自身和子组件的额外约束 |
| decoration | Decoration? | Container的装饰 |
| foregroundDecoration | Decoration? | Container的前景装饰 (decoration在child后面,foregroundDecoration在child前面) |
| margin | EdgeInsetsGeometry? | 外边距 |
| padding | EdgeInsetsGeometry? | 内边距 |
| transform | Matrix4? | 形状转换 |
| transformAlignment | AlignmentGeometry? | 如果指定了形状变化,设置原点相对于容器大小的对齐方式 |