本篇主要整理 flutter 中多组件布局用法。
一、线性布局:Row、Column
1. 定义
- 线性水平或垂直布局。
- 等同于 Android 中的 LinearLayout,很容易上手。
2. 使用说明
以 Row
为例说明,Column
先省略。
-
Row
占用宽度 = 所有水平排列组件宽度总和。 -
Row
占用高度 = 水平排列组件中最高的那个组件高度。 -
Row
中水平方向排列方式通过mainAxisAlignment
来控制,start end center spaceBetween spaceAround spaceEvenly
; - 垂直方向布局通过
crossAxisAlignment
控制,start end center stretch
。 -
Row
占用宽度如果超出屏幕宽度,则会抛overflow 屏幕溢出异常
,此时可以使用Expanded
、Wrap
组件自动换行,或使用可滑动组件。 -
Row
仅占一行,所以直接包裹Text
组件如果过长,不会自动换行,需要使用Expanded
组件包裹。 -
Row
嵌套Row
,最外层的Row
会占满父布局宽度,内层Row
则会按子组件大小布局。若要让内层Row
也占满父布局,则可以使用Expanded
包裹内层布局。[备注:必须是 Column <- Expanded <- Column 才生效,Column <- Expanded <- Row 不生效]
Row(
children: [
Container(
color: Colors.lightGreen,
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: Row(
children: [
Text("hello world. "),
Text("I am Jack "),
],
),
)
),
],
),
)
]
),
二、弹性布局:Flex
1. 定义
A widget that displays its children in a one-dimensional array.
flutter 中的弹性布局,主要使用 Flex
和 Expanded
配合实现。
2. 特性
- 按水平或垂直方向进行布局。
- 如果已知布局方向,则直接使用 Row 或 Column。
- 无滚动特性,若需要在有限空间滚动,则使用
ListView
。 - 如果仅有一个子组件,则应使用
[Align]
或[Center]
。
3. 布局算法
- 详见源码注解。
4. 相关组件
-
[Row]
,Flex 子类,按水平方向布局; -
[Column]
,Flex 子类,按垂直方向布局; -
[Expanded]
,在 Flex 中使用,包裹子组件会占满剩余全部空间; -
[Flexible]
,在 Flex 中使用,包裹子组件只会按自身大小占满部分剩余空间; -
[Spacer]
,按 flex 大小使用空格填充空间。
5. 用法总结
- Flex(direction: Axis.horizontal) = Row;Flex(direction: Axis.vertical) = Column;
- Flex + Expanded(flex: 0) = LinearLayout(weight: 0)
- Flex + Flexible(flex: 0, fit: FlexFit.tight) = Expanded;FlexFit.loose,wrap_content 。
6. Expanded 与 Flexible
(1) Expanded
- 定义:控制位于 Row、Column 或 Flex 组件的权重。
- 特性:必须在 Row、Column 或 Flex 及其子类中使用。
- 同
Flexible
对比,会占满剩余所有空间大小。如果子组件都是使用Expanded
包裹,则根据flex
大小占用剩余空间大小。 -
Expanded extend Flexible
,为Flexible
子类。
(2) Flexible
- 定义:控制位于 Row、Column 或 Flex 组件的权重。
- 特性:必须在 Row、Column 或 Flex 及其子类中使用。
- 同
Expanded
对比,不会占满剩余所有空间大小。
7. 用法示例
Flex(
axis: Axis.horizontal,
children: [
Expanded(
flex: 1,
child: Container(
height: 30.0,
color: Colors.red,
),
),
Spacer(
flex: 1,
),
Expanded(
flex: 2,
child: Container(
height: 30.0,
color: Colors.green,
),
),
],
)
三、流式布局:Wrap、Flow
1. 定义
- 把超出屏幕显示范围会自动折行的布局称为流式布局。Row 只占一行,不会自动换行。
2. 用法
- Flow 一般不常用,因为需要自定义子 widget 布局策略。
- Wrap 同 Android
FlexboxLayout
很像,可自动换行,可自定义组件水平和垂直方向间距:spacing runSpacing
。
四、层叠布局:Stack
- 同 Android
FrameLayout
帧布局很像,可层叠子组件; - 同
Positioned
配合使用,可自定义子组件在父布局中的位置。
五、对齐布局:Align、Center
- 前面讲到
Flex
时提到过,如果只有一个子组件,可以使用对齐组件进行布局。比较简单,暂略。
六、布局组件类图
参考资料: