Flutter弹性布局 #
一、Flex #
1.1 基本概念 #
Flex是Row和Column的底层实现,通过direction属性控制方向。
dart
Flex({
Key? key,
required Axis direction,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection? textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline? textBaseline,
Clip clipBehavior = Clip.none,
List<Widget> children = const <Widget>[],
})
Flex(
direction: Axis.horizontal,
children: [
Expanded(child: Container(color: Colors.red)),
Expanded(child: Container(color: Colors.green)),
],
)
1.2 Flex方向 #
dart
Axis.horizontal
Axis.vertical
1.3 Flex与Row/Column的关系 #
dart
Row(children: [...])
Flex(direction: Axis.horizontal, children: [...])
Column(children: [...])
Flex(direction: Axis.vertical, children: [...])
二、Expanded详解 #
2.1 工作原理 #
Expanded会强制子Widget填满父Widget的剩余空间。
dart
Expanded({
Key? key,
int flex = 1,
Widget? child,
})
2.2 flex属性 #
flex属性决定了子Widget在剩余空间中的比例:
dart
Row(
children: [
Expanded(
flex: 1,
child: Container(height: 100, color: Colors.red),
),
Expanded(
flex: 2,
child: Container(height: 100, color: Colors.green),
),
Expanded(
flex: 3,
child: Container(height: 100, color: Colors.blue),
),
],
)
2.3 常见用法 #
等分空间:
dart
Row(
children: [
Expanded(child: Container(height: 100, color: Colors.red)),
Expanded(child: Container(height: 100, color: Colors.green)),
Expanded(child: Container(height: 100, color: Colors.blue)),
],
)
固定+弹性:
dart
Row(
children: [
Container(width: 100, height: 100, color: Colors.red),
Expanded(child: Container(height: 100, color: Colors.green)),
Container(width: 100, height: 100, color: Colors.blue),
],
)
三栏布局:
dart
Row(
children: [
Container(width: 200, height: 100, color: Colors.red),
Expanded(child: Container(height: 100, color: Colors.green)),
Container(width: 200, height: 100, color: Colors.blue),
],
)
三、Flexible详解 #
3.1 工作原理 #
Flexible允许子Widget根据内容大小或flex比例来分配空间。
dart
Flexible({
Key? key,
int flex = 1,
FlexFit fit = FlexFit.loose,
Widget? child,
})
3.2 FlexFit属性 #
| 值 | 说明 |
|---|---|
| FlexFit.tight | 强制填满空间(同Expanded) |
| FlexFit.loose | 可以小于分配的空间 |
dart
Row(
children: [
Flexible(
flex: 1,
fit: FlexFit.tight,
child: Container(height: 100, color: Colors.red),
),
Flexible(
flex: 1,
fit: FlexFit.loose,
child: Container(width: 50, height: 100, color: Colors.green),
),
],
)
3.3 Expanded vs Flexible #
dart
Column(
children: [
Text('Expanded - 填满剩余空间'),
Row(
children: [
Expanded(
child: Container(
height: 50,
color: Colors.red,
child: Center(child: Text('Expanded')),
),
),
],
),
SizedBox(height: 16),
Text('Flexible - 可以不填满'),
Row(
children: [
Flexible(
child: Container(
width: 100,
height: 50,
color: Colors.green,
child: Center(child: Text('Flexible')),
),
),
],
),
],
)
四、Spacer #
4.1 基本用法 #
Spacer是Expanded的简化版本,专门用于创建空白空间。
dart
Row(
children: [
Text('Left'),
Spacer(),
Text('Right'),
],
)
4.2 flex属性 #
dart
Row(
children: [
Text('Left'),
Spacer(flex: 2),
Text('Middle'),
Spacer(flex: 1),
Text('Right'),
],
)
4.3 Spacer与Expanded的关系 #
dart
Spacer()
Expanded(child: SizedBox())
五、实战示例 #
5.1 底部按钮栏 #
dart
Container(
padding: EdgeInsets.all(16),
child: Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () {},
child: Text('Cancel'),
),
),
SizedBox(width: 16),
Expanded(
child: ElevatedButton(
onPressed: () {},
child: Text('Confirm'),
),
),
],
),
)
5.2 响应式布局 #
dart
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 600) {
return Row(
children: [
Expanded(
flex: 1,
child: Container(color: Colors.red),
),
Expanded(
flex: 2,
child: Container(color: Colors.green),
),
],
);
} else {
return Column(
children: [
Expanded(
child: Container(color: Colors.red),
),
Expanded(
flex: 2,
child: Container(color: Colors.green),
),
],
);
}
},
)
5.3 网格布局 #
dart
Column(
children: [
Expanded(
child: Row(
children: [
Expanded(child: Container(color: Colors.red)),
Expanded(child: Container(color: Colors.green)),
],
),
),
Expanded(
child: Row(
children: [
Expanded(child: Container(color: Colors.blue)),
Expanded(child: Container(color: Colors.yellow)),
],
),
),
],
)
5.4 仪表盘布局 #
dart
Column(
children: [
Expanded(
flex: 2,
child: Container(
color: Colors.blue,
child: Center(child: Text('Main Content')),
),
),
Expanded(
child: Row(
children: [
Expanded(
child: Container(
color: Colors.red,
child: Center(child: Text('Stats 1')),
),
),
Expanded(
child: Container(
color: Colors.green,
child: Center(child: Text('Stats 2')),
),
),
Expanded(
child: Container(
color: Colors.orange,
child: Center(child: Text('Stats 3')),
),
),
],
),
),
],
)
六、性能优化 #
6.1 避免过度嵌套 #
dart
Column(
children: [
Expanded(child: Container(color: Colors.red)),
Expanded(child: Container(color: Colors.green)),
],
)
6.2 使用const #
dart
Row(
children: const [
Expanded(child: SizedBox(height: 100)),
Expanded(child: SizedBox(height: 100)),
],
)
6.3 避免不必要的Flexible #
dart
Row(
children: [
Container(width: 100, color: Colors.red),
Container(width: 100, color: Colors.green),
],
)
七、总结 #
7.1 Widget对比 #
| Widget | 特点 |
|---|---|
| Flex | 底层实现,可设置方向 |
| Expanded | 强制填满剩余空间 |
| Flexible | 可以不填满空间 |
| Spacer | 创建空白空间 |
7.2 下一步 #
掌握了弹性布局后,让我们学习 流式布局!
最后更新:2026-03-28