线性布局(Row和Column)
Row
Row可以在水平方向排列其子widget
Column
Column可以在垂直方向排列其子组件。参数和Row一样,不同的是布局方向为垂直,主轴纵轴正好相反
特殊情况
如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有最外面的Row或Column会占用尽可能大的空间,里面Row或Column所占用的空间为实际大小。需要搭配Expanded使用。
弹性布局(Flex)
Flex
Flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用Row或Column会方便一些,因为Row和Column都继承自Flex,参数基本相同,所以能使用Flex的地方基本上都可以使用Row或Column。Flex本身功能是很强大的,它也可以和Expanded组件配合实现弹性布局。
Expanded
可以按比例“扩伸” Row、Column和Flex子组件所占用的空间。flex参数为弹性系数,如果为0或null,则child是没有弹性的,即不会被扩伸占用的空间。如果大于0,所有的Expanded按照其flex的比例来分割主轴的全部空闲空间。
流式布局
在介绍Row和Colum时,如果子widget超出屏幕范围,则会报溢出错误
Wrap
超出显示范围后Wrap会折行
Flow
一般很少会使用Flow,因为其过于复杂,需要自己实现子widget的位置转换,在很多场景下首先要考虑的是Wrap是否满足需求。Flow主要用于一些需要自定义布局策略或性能要求较高(如动画中)的场景。
Flow有如下优点:
性能好;Flow是一个对子组件尺寸以及位置调整非常高效的控件,Flow用转换矩阵在对子组件进行位置调整的时候进行了优化:在Flow定位过后,如果子组件的尺寸或者位置发生了变化,在FlowDelegate中的paintChildren()方法中调用context.paintChild 进行重绘,而context.paintChild在重绘时使用了转换矩阵,并没有实际调整组件位置。
灵活;由于我们需要自己实现FlowDelegate的paintChildren()方法,所以我们需要自己计算每一个组件的位置,因此,可以自定义布局策略。
缺点:
使用复杂。
不能自适应子组件大小,必须通过指定父容器大小或实现TestFlowDelegate的getSize返回固定大小。
层叠布局 Stack、Positioned
Stack允许子组件堆叠,而Positioned用于根据Stack的四个角来确定子组件的位置。
对齐与相对定位(Align)
Align
Align 组件可以调整子组件的位置,并且可以根据子组件的宽高来确定自身的的宽高
Align和Stack对比
可以看到,Align和Stack/Positioned都可以用于指定子元素相对于父元素的偏移,但它们还是有两个主要区别:
定位参考系统不同;Stack/Positioned定位的的参考系可以是父容器矩形的四个顶点;而Align则需要先通过alignment 参数来确定坐标原点,不同的alignment会对应不同原点,最终的偏移是需要通过alignment的转换公式来计算出。
Stack可以有多个子元素,并且子元素可以堆叠,而Align只能有一个子元素,不存在堆叠。