
一:Flutter布局过程
Flutter 中有两种布局模型:
1、基于 RenderBox 的盒模型布局。
2、基于 Sliver ( RenderSliver ) 按需加载列表布局。
这两种模型的布局过程都一样, 如下所示:
首先,上层 widget 向下层 widget 传递约束条件(BoxConstraints); constraints go down!
然后,下层 widget 向上层 widget 传递大小信息。sizes go up!
最后,上层 widget 决定下层 widget 的位置。Parent sets position!
1.1 布局过程
-
Widget 会通过它的 父级 获得自身的约束。约束实际上就是 4 个浮点类型的集合:最大/最小宽度,以及最大/最小高度。
-
然后,这个 widget 将会逐个遍历它的 children 列表。向子级传递 约束(子级之间的约束可能会有所不同),然后询问它的每一个子级需要用于布局的大小。
-
然后,这个 widget 就会对它子级的 children 逐个进行布局。(水平方向是 x 轴,竖直是 y 轴)
-
最后,widget 将会把它的大小信息向上传递至父 widget(包括其原始约束条件)
1.2widget分类
总的来说,box 分成以下几类,它们有不同的处理大小限制的方式:
1、尽可能地撑满。例如 Center 和 ListView 使用的 box。
2、尽可能地保持与子节点一致。例如 Transform 和 Opacity 使用的 box。
3、尽可能地布局为指定大小。例如 Image 和 Text 使用的 box。
像 Container 这样的 widget 会根据不同的参数进行不同的布局。 Container 的默认构造会让其尽可能地撑满大小限制,但如果你设置了 width,它就会尽可能地遵照你设置的大小。
其他像 Row 和 Column(Flex 系列)这样的 widget 会根据它们的限制进行不同的布局。
二:Flutter 布局约束与常见 Widgets 对应解析
BoxConstraints
是 Flutter 布局系统的核心组件之一,用于定义父组件对子组件的尺寸限制。以下是不同类型的约束,以及常见适用的 Widgets。
//BoxConstraints的定义
const BoxConstraints({
this.minWidth = 0.0, //最小宽度
this.maxWidth = double.infinity, //最大宽度
this.minHeight = 0.0, //最小高度
this.maxHeight = double.infinity //最大高度
})
/// Creates box constraints that is respected only by the given size.
BoxConstraints.tight(Size size)
: minWidth = size.width,
maxWidth = size.width,
minHeight = size.height,
maxHeight = size.height;