Flutter组件解析之Container
Flutter使用声明式来写UI,跟SwiftUI类似,非常先进。但是与HTML或以前的iOS布局方式差异相当大,这里主要通过介绍万金油组件Container来熟悉这种写法。
一、源码解析
Container实现了很多功能,很多时候有多种需要的时候一个Container就可以搞定。
我们来看看Container的创建源码,每个参数其实都是嵌套了一层小组件,这里把相应的小组件写在后面注释里面了。
Container({
Key key,
this.alignment, // Align
this.padding, // Padding
this.color, // ColoredBox
this.decoration, // DecoratedBox
this.foregroundDecoration, // DecoratedBox
double width, // ConstrainedBox
double height, // ConstrainedBox
BoxConstraints constraints, // ConstrainedBox
this.margin, // Padding
this.transform, // Transform
this.child,
this.clipBehavior = Clip.none, // ClipPath
})
可以点进去看build方法,这里列出部分代码
Widget current = child;
...
final EdgeInsetsGeometry effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null)
current = Padding(padding: effectivePadding, child: current);
if (color != null)
current = ColoredBox(color: color, child: current);
if (constraints != null)
current = ConstrainedBox(constraints: constraints, child: current);
if (margin != null)
current = Padding(padding: margin, child: current);
比如
Padding(padding: padding, child: ColoredBox(color: color, child: child))
用Container表示就是下面这样的
Container(color: color, padding: padding, child: child)
不止是Container,还有很多其他组件其实也都是做了一些嵌套而已,这也是声明式UI的一大特色。在Flutter中,Container组件也正是组合优先于继承的实例。
二、属性介绍
1、alignment
对齐方向
需要注意的是Container默认大小是随子组件的,如果设置了这个alignment参数后Container会变成大小会跟随父组件。
2、width、height、constraints
这三个属性会合成一个约束通过ConstrainedBox嵌套。
它们同时出现的时候width、height优先。
3、padding和margin
这两个比较容易用混,我们通过下面一个例子来理解

源码如下
Center(
child: Container(
color: Colors.black,
child: Container(
color: Colors.red,
margin: EdgeInsets.all(20),
padding: EdgeInsets.all(10),
child: Container(color: Colors.yellow, height: 10, width: 10),
),
),
)
可以看到红色部分就是padding,在child的外面扩充。
黑色部分就是margin产生的,可以理解为是我虽然只有红色这么大,但是上层你必须给我黑色这么大的空间。
其实build里面的源码嵌套顺序也可以看出来,先设置padding,然后再设置背景颜色和装饰这些,最后再设置margin,相当于最后再在外面套了一个空框。
4、color和 decoration
都是设置背景,color和 decoration是互斥的,两个只能设置一个, decoration功能更强大,可以设置非常炫酷的效果。
5、foregroundDecoration
前台装饰,先绘制背景和child,最后再绘制 foregroundDecoration,会挡住child。
6、transform
矩阵变换,可以是移动、缩放、绕x或y或z轴旋转、或者多个复合的变换。
7、clipBehavior枚举
none:无模式hardEdge:裁剪速度稍快,但容易失真,有锯齿。
antiAlias:裁剪边缘抗锯齿,使得裁剪更平滑,这种模式裁剪速度比antiAliasWithSaveLayer快,但是比hardEdge慢,该模式常用于圆形和弧形之类的形状裁剪。
antiAliasWithSaveLayer:裁剪后具有抗锯齿特性并分配屏幕缓冲区,所有后续操作在缓冲区进行,然后再进行裁剪和合成。
默认是none,这个属性一般情况下用不到。
结束语:Container是非常常用且实用的小组件,很有必要深入理解它。