Flutter 布局学习笔记

1,383 阅读3分钟

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

未完待续……