一、基础用法(核心入门)
Column 是 Jetpack Compose 中最基础、最核心的垂直布局容器,作用是将子组件按「从上到下」的顺序垂直排列,类比原生 Android 的 LinearLayout(orientation="vertical")。它是 Compose 布局体系的基石,掌握其用法和细节,能解决 80% 的垂直排列场景。
1、最简示例(无任何配置)
@Composable
fun BasicColumnDemo() {
// 最基础的 Column:垂直排列子组件
Column {
// 子组件1:文本
Text(text = "第一项", fontSize = 16.sp)
// 子组件2:按钮
Button(onClick = { /* 点击逻辑 */ }) {
Text("第二项(按钮)")
}
// 子组件3:图片(示例)
Icon(
imageVector = Icons.Default.Home,
contentDescription = "第三项(图标)",
modifier = Modifier.size(24.dp)
)
}
}
- 效果:Text → Button → Icon 从上到下依次排列;
- 核心特点:Column 会根据子组件的总高度自适应自身高度,宽度默认包裹子组件的最大宽度。
2、限制 Column 尺寸(必学)
默认 Column 是 “包裹内容”,实际开发中需限制其尺寸(比如占满屏幕):
@Composable
fun ColumnWithSize() {
Column(
modifier = Modifier
.fillMaxSize() // 占满父容器的宽高(比如屏幕)
.background(Color.LightGray) // 背景色,方便看范围
) {
Text("占满屏幕的 Column", modifier = Modifier.padding(8.dp))
}
}
常用尺寸修饰符:
fillMaxSize():占满父容器宽高;fillMaxWidth():占满父容器宽度,高度包裹内容;fillMaxHeight():占满父容器高度,宽度包裹内容;width(200.dp)/height(300.dp):固定宽 / 高;size(200.dp):固定宽高。
二、核心参数(掌握布局控制)
Column 的核心能力来自 3 个关键参数,掌握它们就能精准控制子组件的排列方式:
| 参数 | 作用 | 常用值 |
|---|---|---|
modifier | 控制 Column 自身的尺寸、背景、交互等(所有 Compose 组件通用) | fillMaxSize()/background()/padding()/clickable() |
horizontalAlignment | 子组件在水平方向的对齐方式(Column 主轴是垂直,交叉轴是水平) | Alignment.Start(左对齐,默认)、Alignment.CenterHorizontally(居中)、Alignment.End(右对齐) |
verticalArrangement | 子组件在垂直方向的排列方式(间距、对齐) | Arrangement.Top(顶部,默认)、Arrangement.Center(垂直居中)、Arrangement.Bottom(底部)、Arrangement.SpacedBy(8.dp)(子项间距) |
1. 水平对齐(horizontalAlignment)
@Composable
fun ColumnHorizontalAlignment() {
Column(
modifier = Modifier
.fillMaxWidth() // 必须占满宽度,对齐才生效
.background(Color.LightGray),
// 子组件水平居中
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("水平居中的文本")
Button(onClick = {}) { Text("水平居中的按钮") }
}
}
⚠️ 关键:horizontalAlignment 需配合 fillMaxWidth() 使用,否则 Column 宽度包裹内容,对齐效果不可见。
2. 垂直排列(verticalArrangement)
@Composable
fun ColumnVerticalArrangement() {
Column(
modifier = Modifier
.fillMaxSize() // 占满屏幕,垂直排列才生效
.background(Color.LightGray),
horizontalAlignment = Alignment.CenterHorizontally,
// 垂直居中 + 子项间距16dp
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.CenterVertically)
) {
Text("第一项")
Text("第二项")
Text("第三项")
}
}
常用 Arrangement 类型:
Arrangement.Top:子组件靠顶部排列;Arrangement.Center:子组件垂直居中;Arrangement.Bottom:子组件靠底部排列;Arrangement.SpaceBetween:子组件均匀分布(首尾贴边,中间间距相等);Arrangement.SpaceAround:子组件周围间距相等;Arrangement.SpacedBy(8.dp):子组件之间固定间距(最常用)。
4. 子组件权重(weight):占满剩余空间
weight 是子组件的修饰符,用于让子组件占满 Column 的剩余空间,类比原生 LinearLayout 的 layout_weight:
@Composable
fun ColumnWithWeight() {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color.LightGray)
) {
// 固定高度的头部(50dp)
Text(
text = "头部",
modifier = Modifier
.height(50.dp)
.fillMaxWidth()
.background(Color.Gray)
)
// 占剩余60%空间的内容区
Box(
modifier = Modifier
.weight(0.6f) // 权重0.6
.fillMaxWidth()
.background(Color.Blue)
)
// 占剩余40%空间的底部
Box(
modifier = Modifier
.weight(0.4f) // 权重0.4
.fillMaxWidth()
.background(Color.Green)
)
}
}
⚠️ 注意事项:
weight必须配合fillMaxWidth()/fillMaxHeight()使用(否则权重失效);- 给子组件加
weight后,其height会被忽略(权重优先); - 滚动布局(加了
verticalScroll)中,weight失效(滚动布局无固定剩余空间)。
三、进阶技巧(解决实际开发问题)
1. 给 Column 加滚动(处理内容溢出)
Column 默认不滚动,子组件总高度超屏时会溢出报错,需手动加滚动:
@Composable
fun ScrollableColumnDemo() {
Column(
modifier = Modifier
.fillMaxSize()
// 核心:开启垂直滚动
.verticalScroll(rememberScrollState())
) {
// 模拟30个子项(总高度超屏)
repeat(30) {
Text(
text = "滚动项 $it",
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
}
}
}
-
rememberScrollState():创建与 Composable 绑定的滚动状态(确保滚动位置不随重组丢失); -
核心限制:加滚动后,Column 仍会一次性渲染所有子项,子项 > 20 时建议换
LazyColumn。
2. 给 Column 加间距(两种方式)
- 方式 1:
verticalArrangement = Arrangement.spacedBy(8.dp)(子项统一间距,推荐); - 方式 2:手动给子组件加
Spacer(自定义间距,灵活)。
@Composable
fun ColumnWithSpacing() {
Column(
modifier = Modifier.fillMaxWidth(),
// 方式1:统一间距
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text("统一间距项1")
Text("统一间距项2")
// 方式2:自定义间距(比如加大某两个子项的间距)
Spacer(modifier = Modifier.height(20.dp)) // 20dp间距
Text("自定义间距项3")
}
}
3. 嵌套 Column(局部垂直布局)
实际开发中常嵌套 Column(比如 “外层大布局 + 内层局部布局”):
@Composable
fun NestedColumnDemo() {
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
// 外层头部
Text("页面头部", fontSize = 20.sp, fontWeight = FontWeight.Bold)
// 内层 Column:局部垂直布局
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.background(Color.LightGray),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("内层项1")
Button(onClick = {}) { Text("内层按钮") }
}
// 外层底部
Text("页面底部", modifier = Modifier.padding(top = 16.dp))
}
}
⚠️ 避坑:内层 Column 不要加 fillMaxSize(),否则会撑满外层剩余空间,导致外层滚动异常(用 wrapContentHeight() 替代)。
4. Column 加点击事件
给 Column 整体加点击事件(覆盖所有子组件区域):
@Composable
fun ClickableColumnDemo() {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable { // 整体点击事件
println("Column 被点击了")
}
.padding(16.dp)
.background(Color.LightGray)
) {
Text("点击Column任意位置都响应")
Button(onClick = { println("按钮单独点击") }) { // 子组件点击事件优先
Text("按钮")
}
}
}
-
优先级:子组件的点击事件 > Column 的点击事件;
-
若想让 Column 点击覆盖子组件,需给子组件加
pointerEvents(PointerEvents.None)(禁用子组件点击)。
四、常见坑点 & 避坑指南
| 问题现象 | 原因 | 解决方案 |
|---|---|---|
| Column 内容溢出报错 | 子组件总高度超 Column 高度,且未加滚动 | 1. 少量子项:加 verticalScroll;2. 大量子项:换 LazyColumn |
| 水平对齐不生效 | Column 宽度是 “包裹内容”,无多余空间对齐 | 给 Column 加 fillMaxWidth() |
| weight 不生效 | 1. 未加 fillMaxWidth()/fillMaxHeight();2. Column 加了滚动 | 1. 补充尺寸修饰符;2. 滚动布局中不用 weight |
| 嵌套 Column 滚动失效 | 内层 Column 加了 fillMaxSize(),撑满外层空间 | 内层 Column 用 wrapContentHeight() |
| Column 重组卡顿 | 子组件数量过多(>20),一次性渲染所有子项 | 换 LazyColumn;或用 remember 缓存不变子组件 |