「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」。
前言
前文【Flutter】基础组件之Text简单介绍了Text组件,本文就来介绍下Container组件。
一: Container
Container是将普通绘画、定位和调整widget大小相结合的便利widget。
1.1 Container结构
Container通常作为其他widget的容器使用,所以最主要的属性就是child(子widget,类似于iOS的subview)。
Container首先使用padding包围child,然后对填充范围应用附加constraints(如果其中一个非空,则将宽度和高度合并为约束),最后,Container被margin描述的其他空位包围。
在绘制过程中,Container首先应用给定的transform,然后绘制decoration以填充填充范围,然后绘制child,最后绘制foregroundDecoration,也填充填充范围。
没有子widget的Container会尽量大。除非传入的constraints是unbounded(无界的),在这种情况下,它们会尽量小。
带有子widget的Container,会根据子widget的大小调整自身大小。但是如果构造函数中包含width、height和constraints ,则会按照构造函数的参数来进行自身大小的调节。
默认情况下,对于所有hit test,Container都返回false。如果指定了color属性,则hit test由ColoredBox处理,它始终返回true。如果指定了decoration或foregroundDecoration属性,则通过Decoration.hitTest处理hit test。
1.2 Container布局
由于Container结合了许多其他widget,每个widget都有自己的布局行为,所以Container的布局行为有些复杂。
概要:
Container尝试,顺序是:遵循alignment、根据child调整自身大小、遵循width、height和constraints、扩展自身以适应父部件、调节自身到尽可能小。
更具体地说:
-
如果没有子部件、
width、height和constraints,并且父部件提供了unbounded constraints,则Container会尝试将自身调节到尽可能小。 -
如果没有子部件,也没有
alignment(对齐方式),但是提供了width、height和constraints,那么Container将根据这些约束和父部件的约束,将自身调节到尽可能小。 -
如果没有子部件、
width、height、constraints和alignment,但父部件提供了bounded constraints,则Container将展开以适应父部件提供的约束。 -
如果有
alignment,并且父部件提供了unbounded constraints,那么Container将尝试围绕子部件调整自身大小。 -
如果有
alignment,并且父部件提供了bounded constraints,则Container将尝试展开以适应父部件,然后根据alignment将子部件定位到自身中。 -
如果有子部件,但没有
width、height、constraints和alignment,Container将约束从父部件传递给子部件,并调整自身大小以匹配子部件。 -
margin和padding属性也会影响布局,如这些属性的文档中所述(它们的效果只是增强了上述规则)。decoration可以隐含地增加padding。
1.3 Container基础属性
-
key:widget唯一标识,用于验证、更新。 -
alignment:控制child的对齐方式,如果container或者container的父组件尺寸大于child的尺寸,这个属性设置会起作用。 -
padding:decoration内部的空白区域。如果有child,位于padding内部。 -
color:Container背景色。如果设置foregroundDecoration,可能会遮盖color效果。 -
decoration:绘制在child后面的装饰,使用color属性指定简单的纯色。 -
foregroundDecoration:在child面前绘制的装饰。 -
constraints:应用于child的额外约束, -
margin:环绕decoration和child的空白区域。 -
transform:绘制容器之前要应用的变换矩阵。 -
transformAlignment:如果指定了transform,则为原点相对于Container大小的对齐方式。 -
child:Container的子部件。 -
clipBehavior:剪切行为,Container.decoration不为null时有效。
padding和margin的区别:padding包含在content内,而margin则是外部边界,padding区域可以响应交互,而margin区域不可以。
1.4 Container使用举例
void main() {
// 执行runApp,传入widget,就会显示到屏幕上了
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
margin: EdgeInsets.all(10),
color: Colors.white,
alignment: Alignment.center,
child: Container(
constraints: BoxConstraints.expand(
height: Theme.of(context).textTheme.headline4!.fontSize! * 1.1 + 200,
),
padding: const EdgeInsets.all(10.0),
color: Colors.blue[600],
alignment: Alignment.center,
child: Text('Hello Flutter',
style: Theme.of(context)
.textTheme
.headline4!
.copyWith(color: Colors.white),
textDirection: TextDirection.ltr,
),
transform: Matrix4.rotationZ(0.1),
),
);
}
}
运行效果:
关于Container的更多内容,请移步官方文档Container。
期待关注,持续输出。