Compose Foundation
Compose 底层 · androidx.compose.foundation
Row、Column 与 Box1.13.0-alpha01
用主轴、交叉轴、权重和约束选择基础布局。
最后更新 2026-08-01
三个容器
// Row:水平排列
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
) {
Text("标题", Modifier.weight(1f))
IconButton(onClick = onMore) { Icon(...) }
}
// Column:垂直排列
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
) { ... }
// Box:叠放 + 对齐
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { ... }| 参数 | 作用 |
|---|---|
Arrangement | 主轴分布(Start/Center/SpaceBetween/SpaceEvenly/spacedBy) |
Alignment(Box)/ verticalAlignment(Row)/ horizontalAlignment(Column) | 交叉轴/定位 |
weight:主轴空间分配
Row(Modifier.fillMaxWidth()) {
Box(Modifier.weight(1f)) // 占剩余空间的 1 份
Box(Modifier.weight(2f)) // 占 2 份
}weight是 RowScope/ColumnScope 的父数据(Modifier.weight只能在 Row/Column 内部用)。- Row 先测量非权重项,剩余空间按权重比例分配。
- 不是任意父布局认识的通用 Modifier——拿到错误 scope 编译报错。
fill、wrap 和 required
Modifier.fillMaxWidth() // 占满父宽度(约束范围)
Modifier.wrapContentSize() // 按内容尺寸
Modifier.requiredSize(48.dp) // 强制目标尺寸(可能超出父约束)
Modifier.widthIn(min, max) // 在范围内取尺寸尺寸 modifier 改变传给子节点的 Constraints。遇到”尺寸没生效”:
- 检查父布局给的约束(是否固定/无界)。
- 检查 modifier 顺序(padding 在 size 前后影响可用空间)。
Insets 由谁消费
// 只在一层消费系统 Insets
Scaffold(
contentWindowInsets = WindowInsets.safeDrawing,
) { innerPadding ->
LazyColumn(Modifier.padding(innerPadding)) { ... }
}windowInsetsPadding、safeDrawingPadding、imePadding位于 Foundation。- 只在负责系统边界的层使用;父层已消费的会影响子层剩余值。
- 不要到处重复加同一份 padding(双倍留白)。
常见陷阱
- weight 用错 scope:
Modifier.weight只能在 Row/Column 内。 - fillMaxWidth 后 wrapContent 冲突:顺序决定谁生效。
- Insets 重复消费:父加一份、子又加一份 → 双倍间距。
- Box 对齐忘设置:默认 TopStart,叠放元素位置不对。
复制即用
@Composable
fun ToolbarRow(
title: String,
onBack: () -> Unit,
onMore: () -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(onClick = onBack) { Icon(Icons.Default.ArrowBack, "返回") }
Text(title, Modifier.weight(1f), overflow = TextOverflow.Ellipsis, maxLines = 1)
IconButton(onClick = onMore) { Icon(Icons.Default.MoreVert, "更多") }
}
}要点
- Row/Column 用 Arrangement 管主轴,Alignment 管交叉轴;Box 管叠放。
weight是 Row/Column scope 的父数据,先测非权重项再分剩余。- 尺寸 modifier 改 Constraints;排查”尺寸没生效”看约束和顺序。
- Insets 单层消费;scaffold innerPadding 往下传。