在 Flutter 中,Column 是一个用于垂直排列子组件的布局容器,类似于 Android 的 LinearLayout(垂直方向)或 Web 的 Flexbox 布局。
以下是 Column 的详细用法解析,涵盖基础属性、布局行为、常见场景及注意事项。
一、基本概念
Column 会将所有子组件(children)按垂直方向依次排列。它的核心特性包括:
- 主轴(Main Axis) :垂直方向(从上到下)。
- 交叉轴(Cross Axis) :水平方向(从左到右)。
- 子组件对齐:通过
mainAxisAlignment和crossAxisAlignment控制对齐方式。 - 尺寸行为:默认尽可能占用最大可用高度(但受父组件约束影响)。
二、构造函数参数详解
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:子组件从顶部开始排列(默认)。
MainAxisAlignment.end:子组件从底部开始排列。
MainAxisAlignment.center:子组件居中。
MainAxisAlignment.spaceBetween:首尾子组件贴边,中间均匀分布。
MainAxisAlignment.spaceAround:子组件周围均匀分布间距。
MainAxisAlignment.spaceEvenly:子组件和间距完全均匀分布, 和spaceAround的区别在于两边的边距不一样,spaceAround是两边的边距是中间的一半,而spaceEvenly是所有间距都一样。
示例:均匀分布子组件
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:左对齐。
CrossAxisAlignment.end:右对齐。
CrossAxisAlignment.center:水平居中(默认)。
CrossAxisAlignment.stretch:拉伸子组件至填满水平空间。
CrossAxisAlignment.baseline:按文本基线对齐(需设置textBaseline,否则会报错),这种对齐方式用的非常少。
示例:水平拉伸子组件
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 分配剩余空间
让中间子组件占据剩余高度:
Column(
children: [
Container(height: 100, color: Colors.red),
Expanded( // 占据剩余空间
child: Container(color: Colors.green),
),
Container(height: 100, color: Colors.blue),
],
)
3. 添加间距
- 使用
SizedBox:固定间距。 - 使用
Spacer:按比例分配剩的空间。
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 错误。解决方案:
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: [/* 子组件 */],
),
)
六、注意事项
-
默认无滚动
Column本身不支持滚动,需手动添加SingleChildScrollView或改用ListView。 -
Expanded与FlexibleExpanded是Flexible(fit: FlexFit.tight),强制占据剩余空间。Flexible允许子组件按比例分配空间(flex属性)。
-
基线对齐 若使用
CrossAxisAlignment.baseline,需指定textBaseline(如TextBaseline.alphabetic)。 -
性能优化 若子组件数量多或高度动态,优先使用
ListView或CustomScrollView以支持懒加载。
七、总结
Column 是 Flutter 中实现垂直布局的核心组件,适用于:
- 表单、设置项、列表项等垂直排列的 UI。
- 结合
Expanded或Flexible分配空间。 - 嵌套其他布局组件(如
Row、Container)。
通过灵活调整 mainAxisAlignment、crossAxisAlignment 和子组件的尺寸,可以快速实现复杂的垂直布局结构。若需滚动,务必结合可滚动组件(如 SingleChildScrollView)使用。