Flutter 官方文档中介绍了所有布局部件(Widget),我打算将其翻译成前端能看懂的教程,遂有此文。
所有部件我都用代码解释,如果你需要运行代码,可以提前下载初始代码,htps://github.com/FrankFang/pz11hUSS3pSJ 然后改写第 54 至 60 行并运行。
独子布局部件
这些部件只支持单个子元素,使用 child 属性可指定子部件。
Container
最普通的布局容器,类似于 div,支持的属性除了图中的 color、width、height,还有 padding、margin、alignment、constraints、decoration、foregroundDecoration、transform、clipBehavior。
child: Text('hi')
padding
嵌套 + margin
align:内容对齐方式
constraints:约束条件
比如最大宽度(注意我删掉了 width),如果不加 maxWidth,当前 Container 会自动横向延展顶到左右两边,这一点跟 div 很像。
decoration:背景装饰
color 属性其实就是 decoration 的简写。
decoration 还可以支持渐变
还可以支持图片背景
还支持九宫格图片(centerSlice),更多细节可以查看这篇教程 和 BoxDecoration 的文档
foregroundDecoration:前景装饰
其中 Color(0x99ff0000) 里面的 99 是不透明度。如果把 99 改成 ff,已经就是完全不透明,那么 hi 就看不见了。
transfrom:变形
clipBehavior
用来优化 clip,目前用不到。
Center
自动向上下左右延展的容器,其 child 居中。不能指定宽高,大部分时候只接受 child 这一个参数。
上面是没加 Center 的 Text,下面是加了 Center 的 Text。
Padding
只接受 padding 和 child 的 Container。
对于前端来说,Padding 部件的这种设计很令人费解。为什么 Padding 要把 Container 的参数收缩到只接受 padding 和 child,那我直接用 Container 不是更方便吗?这就是不同编程范式造成的思维差异,Flutter 提倡的是「Composition, rather than inheritance」即「组合优于继承」,此处的差异按下不表。
另外,如果你翻看 Container 的代码会发现,当 Container 接受到 padding 参数的时候,会构造出一个 Padding 部件。
// Container 的 build 方法的源码
if (effectivePadding != null)
current = Padding(padding: effectivePadding, child: current);
Margin
并不存在 Margin 部件,前端一定要记住这一点。
Container 源码里是用 Padding 来实现 Margin 的:
// Container 的 build 方法的源码
if (margin != null)
current = Padding(padding: margin, child: current);
如果 Container 即指定了 padding 又指定了 margin,flutter 会使用两层 Padding 部件来实现,即 Container = Padding > Padding > Child,外面的 Padding 部件表示 margin,里面的 Padding 部件表示 padding。
Align
只支持 alignment 和 child 的 Container,可以直接用 Container 代替。
AspectRatio:指定 child 比例的容器
比如这就是一个 1 比 1 的容器。
但如果宽度不够,它就会放弃保持比例,比如下面这个容器就因为宽度不够 500 而使用了屏幕宽度:
ConstrainedBox
只接受 constraints 和 child 的 Container,可以直接用 Container 代替。
Transform
只接受 transform、alignment 和 child 的 Container,可以直接用 Container 代替。
DecoratedBox
未完待续……