[Flutter 基础] - Flutter核心布局组件 - Column

601 阅读4分钟

在 Flutter 中,Column 是一个用于垂直排列子组件的布局容器,类似于 Android 的 LinearLayout(垂直方向)或 Web 的 Flexbox 布局。

以下是 Column 的详细用法解析,涵盖基础属性、布局行为、常见场景及注意事项。


一、基本概念

Column 会将所有子组件(children)按垂直方向依次排列。它的核心特性包括:

  • 主轴(Main Axis) :垂直方向(从上到下)。
  • 交叉轴(Cross Axis) :水平方向(从左到右)。
  • 子组件对齐:通过 mainAxisAlignmentcrossAxisAlignment 控制对齐方式。
  • 尺寸行为:默认尽可能占用最大可用高度(但受父组件约束影响)。

二、构造函数参数详解

Column({
  Key? key,
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 交叉轴对齐方式
  MainAxisSize mainAxisSize = MainAxisSize.max, // 主轴尺寸策略
  TextDirection? textDirection, // 文本方向(影响对齐)
  VerticalDirection verticalDirection = VerticalDirection.down, // 子组件排列方向(上到下/下到上)
  TextBaseline? textBaseline, // 基线对齐(需配合 `crossAxisAlignment: CrossAxisAlignment.baseline`)
  List<Widget> children = const <Widget>[], // 子组件列表
})

三、核心属性解析

1. mainAxisAlignment:主轴对齐方式

控制子组件在垂直方向上的排列方式,可选值:

  • MainAxisAlignment.start:子组件从顶部开始排列(默认)。

image.png

  • MainAxisAlignment.end:子组件从底部开始排列。

image.png

  • MainAxisAlignment.center:子组件居中。

image.png

  • MainAxisAlignment.spaceBetween:首尾子组件贴边,中间均匀分布。

image.png

  • MainAxisAlignment.spaceAround:子组件周围均匀分布间距。

image.png

  • MainAxisAlignment.spaceEvenly:子组件和间距完全均匀分布, 和spaceAround的区别在于两边的边距不一样,spaceAround是两边的边距是中间的一半,而spaceEvenly是所有间距都一样。

image.png

示例:均匀分布子组件

Column(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Container(height: 50, color: Colors.red),
    Container(height: 50, color: Colors.green),
    Container(height: 50, color: Colors.blue),
  ],
)

2. crossAxisAlignment:交叉轴对齐方式

控制子组件在水平方向上的对齐方式,可选值:

  • CrossAxisAlignment.start:左对齐。

image.png

  • CrossAxisAlignment.end:右对齐。

image.png

  • CrossAxisAlignment.center:水平居中(默认)。

image.png

  • CrossAxisAlignment.stretch:拉伸子组件至填满水平空间。

image.png

  • CrossAxisAlignment.baseline:按文本基线对齐(需设置 textBaseline,否则会报错),这种对齐方式用的非常少。

image.png

示例:水平拉伸子组件

Column(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Container(height: 50, color: Colors.red),
    Container(height: 50, color: Colors.green),
  ],
)

3. mainAxisSize:主轴尺寸策略

  • MainAxisSize.max:占满父组件的最大可用高度(默认),。
  • MainAxisSize.min:仅占用子组件所需高度。

说明: 这个属性主要是控制column的高,设置max,则column的高度会尽可能的大,和父组件有一样大,如果设置min,则column只会包裹子组件的大小。 示例:紧凑布局

 Container(
  height: 400,
  width: 200,
  decoration: BoxDecoration(
      border: Border.all(color: Colors.black, width: 2)
  ),
  child: Column(
  //设置max,则column的宽高和Container位height:400,
  //min, 则column的高度位子组件的高度总和,height:50 * 3 = 150
    mainAxisSize: MainAxisSize.max, 
    mainAxisAlignment: MainAxisAlignment.start,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      Container(height: 50, width: 150, color: Colors.red),
      Container(height: 50, width: 150, color: Colors.green),
      Container(height: 50, width: 150, color: Colors.blue),
    ],
  ),

4. verticalDirection:子组件排列方向

  • VerticalDirection.down:从上到下排列(默认)。
  • VerticalDirection.up:从下到上排列。

四、常见使用场景

1. 基础垂直布局

Column(
  children: [
    Text("Username"),
    TextField(),
    ElevatedButton(onPressed: () {}, child: Text("Submit")),
  ],
)

2. 结合 Expanded 分配剩余空间

让中间子组件占据剩余高度:

image.png

Column(
  children: [
    Container(height: 100, color: Colors.red),
    Expanded( // 占据剩余空间
      child: Container(color: Colors.green),
    ),
    Container(height: 100, color: Colors.blue),
  ],
)

3. 添加间距

  • 使用 SizedBox:固定间距。
  • 使用 Spacer:按比例分配剩的空间。

image.png

Column(
  children: [
    Container(height: 50, color: Colors.red),
    SizedBox(height: 20), // 固定间距
    Container(height: 50, color: Colors.green),
    Spacer(),
    Container(height: 50, color: Colors.blue),
    Spacer(),
    Container(height: 50, color: Colors.black),
  ],
)

4. 嵌套 Row 或其它布局组件

Column(
  children: [
    Row(
      children: [
        Icon(Icons.star),
        Text("Rating: 4.5"),
      ],
    ),
    Divider(),
    Text("Description..."),
  ],
)

五、处理溢出问题

当子组件的总高度超出屏幕时,Flutter 会抛出 RenderBox overflow 错误。解决方案:

image.png

Container(
  height: 400,
  width: 200,
  decoration: BoxDecoration(
      border: Border.all(color: Colors.black, width: 2)
  ),
  child: Column(
    children: [
      Container(height: 550, color: Colors.red),
      SizedBox(height: 20), // 固定间距
      Container(height: 50, color: Colors.green),
      Spacer(),
      Container(height: 50, color: Colors.blue),
      Spacer(),
      Container(height: 50, color: Colors.black),
    ],
  ),
),

解决方案有:

1. 包裹 SingleChildScrollView
SingleChildScrollView(
  child: Column(
    children: [/* 多个子组件 */],
  ),
)
2. 使用 ListView(懒加载)
ListView(
  children: [/* 子组件 */],
)
3. 限制父容器高度
Container(
  height: 300, // 固定高度
  child: Column(
    children: [/* 子组件 */],
  ),
)

六、注意事项

  1. 默认无滚动 Column 本身不支持滚动,需手动添加 SingleChildScrollView 或改用 ListView

  2. ExpandedFlexible

    • ExpandedFlexible(fit: FlexFit.tight),强制占据剩余空间。
    • Flexible 允许子组件按比例分配空间(flex 属性)。
  3. 基线对齐 若使用 CrossAxisAlignment.baseline,需指定 textBaseline(如 TextBaseline.alphabetic)。

  4. 性能优化 若子组件数量多或高度动态,优先使用 ListViewCustomScrollView 以支持懒加载。


七、总结

Column 是 Flutter 中实现垂直布局的核心组件,适用于:

  • 表单、设置项、列表项等垂直排列的 UI。
  • 结合 ExpandedFlexible 分配空间。
  • 嵌套其他布局组件(如 RowContainer)。

通过灵活调整 mainAxisAlignmentcrossAxisAlignment 和子组件的尺寸,可以快速实现复杂的垂直布局结构。若需滚动,务必结合可滚动组件(如 SingleChildScrollView)使用。