跳到主要内容

TeamViewer

· 阅读需 3 分钟
Quany
软件工程师

以下是 Flutter 中 Flex 布局(Row/Column) 的深度解析与实用示例,涵盖核心概念、常见场景和代码实践:


1. Flex 布局核心概念

概念说明
主轴 (Main Axis)Row 的水平方向 / Column 的垂直方向(由 mainAxisAlignment 控制子项排列)
交叉轴 (Cross Axis)与主轴垂直的方向(由 crossAxisAlignment 控制对齐)
Expanded占据剩余空间的弹性子项(需指定 flex 权重)
Flexible类似 Expanded,但允许子项不填满可用空间
Spacer占用空白区域的灵活组件(基于 flex 值)

2. 基础用法示例

(1) Row 水平布局

Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // 主轴对齐方式
crossAxisAlignment: CrossAxisAlignment.center, // 交叉轴对齐方式
children: [
Container(width: 50, height: 50, color: Colors.red),
Container(width: 50, height: 50, color: Colors.green),
Container(width: 50, height: 50, color: Colors.blue),
],
)

(2) Column 垂直布局

Column(
mainAxisSize: MainAxisSize.min, // 主轴尺寸最小化
children: [
Text('Header'),
Divider(),
Expanded( // 占据剩余空间
child: ListView(children: [/* ... */]),
),
],
)

3. 弹性空间分配 (Expanded/Flexible)

(1) 按比例分配空间

Row(
children: [
Expanded(
flex: 2, // 权重为2,占2/(2+1) = 66.6%
child: Container(height: 50, color: Colors.red),
),
Expanded(
flex: 1, // 权重为1,占1/(2+1) = 33.3%
child: Container(height: 50, color: Colors.blue),
),
],
)

(2) Flexible 的灵活空间

Row(
children: [
Flexible(
fit: FlexFit.loose, // 允许子项小于可用空间
child: Container(
width: 100, // 最大宽度100,不足时按实际内容调整
color: Colors.yellow,
),
),
Expanded( // 强制填满剩余空间
child: Container(height: 50, color: Colors.green),
),
],
)

4. 高级布局技巧

(1) 使用 Spacer 填充空白

Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
Spacer(flex: 1), // 占据剩余空间
Container(width: 50, height: 50, color: Colors.blue),
],
)

(2) 嵌套布局 (Row + Column)

Column(
children: [
Row(
children: [
Icon(Icons.star),
SizedBox(width: 8),
Expanded(
child: Text('Flutter Flex Layout Guide'),
),
],
),
Divider(),
Expanded(
child: Row(
children: [
Expanded(flex: 1, child: Sidebar()),
VerticalDivider(),
Expanded(flex: 3, child: ContentArea()),
],
),
),
],
)

5. 常见问题与解决方案

(1) 内容溢出 (Overflow)

当子项总宽度超过主轴空间时,使用 ListViewSingleChildScrollView 包裹:

SingleChildScrollView(
scrollDirection: Axis.horizontal, // 水平滚动
child: Row(children: [/* 多个宽子项 */]),
)

(2) 动态调整布局

结合 MediaQuery 实现响应式布局:

Row(
children: [
if (MediaQuery.of(context).size.width > 600) // 大屏显示侧边栏
Expanded(flex: 1, child: Sidebar()),
Expanded(flex: 3, child: MainContent()),
],
)

6. 布局调试工具

  • Flutter Inspector:实时查看布局结构
  • Debug Painting:添加调试边框
    MaterialApp(
    debugShowCheckedModeBanner: false,
    debugShowMaterialGrid: true, // 显示网格
    );

7. 性能优化

  • 避免在 Row/Column 中使用大量子项(超过20个时,优先考虑 ListViewGridView
  • 对复杂子项使用 const 构造函数减少重建:
    Row(
    children: const [
    Icon(Icons.access_alarm),
    SizedBox(width: 10),
    Text('Static Content'),
    ],
    )

通过以上方法,你可以高效利用 Flutter 的 Flex 布局构建自适应 UI。遇到具体问题时,可结合 FlexibleExpanded 动态调整空间分配。

微信公众号

微信公众号