定位:入门 / 常用技能 适合:能写单个组件,但一排版就乱、Modifier 顺序总是搞反的同学
一、Compose 布局的心智:先「测量」后「摆放」
Compose 的布局分三步:测量 → 摆放 → 绘制 ,而且有个铁律:每个子组件只被测量一次 。这一点和传统 View 的 onMeasure(父子可以来回协商多次)很不一样。
对小白来说,你只需要记住三块积木,能解决 90% 的排版:
Column:竖着排(垂直方向)。Row:横着排(水平方向)。Box:叠着排(类似 FrameLayout,后写的盖在前写的上面)。
配合 Modifier(修饰符)控制大小、边距、背景、点击等。
二、Modifier 顺序:最容易踩的坑
Modifier 可以链式调用,但顺序会显著影响结果。看这个经典案例:
kotlin
// 案例 A:先 padding,再 background
Box(
modifier = Modifier
.padding(20.dp)
.background(Color.Red)
)
// 案例 B:先 background,再 padding
Box(
modifier = Modifier
.background(Color.Red)
.padding(20.dp)
)
结果完全不同:
- 案例 A:先在四周留出 20dp 空白,再在剩余区域画红色背景。红色区域被 padding 挤小了。
- 案例 B:先画满红色背景,再在红色内部留 20dp 空白。红色区域撑满原尺寸。
一句话记忆:Modifier 是从外到内、从左到右依次「包裹」的。左边的先作用在外层,右边的作用在内层。
想清楚这条,size、clickable、clip 等顺序问题都能自己推出来。
三、常用布局速查表
| 需求 | 用什么 | 关键参数 |
|---|---|---|
| 竖排 | Column |
verticalArrangement(主轴间距)、horizontalAlignment(交叉轴对齐) |
| 横排 | Row |
horizontalArrangement、verticalAlignment |
| 叠放/定位 | Box |
Alignment |
| 复杂约束 | ConstraintLayout |
createRefs、约束关系 |
| 铺满 | Modifier.fillMaxSize() |
注意 fillMaxWidth/fillMaxHeight |
| 间距 | Modifier.padding() |
四边或单边 |
| 宽高 | Modifier.size(width, height) |
固定尺寸 |
Arrangement 控制主轴上的间距(SpaceBetween、SpaceAround、spacedBy),Alignment 控制交叉轴上的对齐。这两个词区分清楚,排版就通了一半。
四、Scaffold:页面的「骨架」
写一个标准页面,别从零堆 Column,直接用 Scaffold。它帮你准备好 TopBar(顶栏)、BottomBar(底栏)、FloatingActionButton(悬浮按钮)和内容区。
kotlin
Scaffold(
topBar = { TopAppBar(title = { Text("标题") }) },
bottomBar = { BottomAppBar { Text("底栏") } },
floatingActionButton = { FloatingActionButton(onClick = {}) { Text("+") } }
) { innerPadding ->
// 内容区:务必应用 innerPadding,否则会被系统栏/顶栏挡住
Column(modifier = Modifier.padding(innerPadding)) {
Text("页面内容")
}
}
小白最容易忘的是 innerPadding :Scaffold 的 lambda 会传给你一个 PaddingValues,它包含了顶栏、底栏、系统状态栏占用的空间。内容区一定要 Modifier.padding(innerPadding),否则内容会被遮挡。
五、Material 3 主题:一套配色吃遍天下
Compose 默认基于 Material 3 。你不需要手写颜色值,而是通过 MaterialTheme.colorScheme 取语义化颜色:
kotlin
Text(color = MaterialTheme.colorScheme.primary) // 主色
Surface(color = MaterialTheme.colorScheme.surface) // 表面色
好处:换主题(浅色/深色)时,整套颜色自动切换。做暗黑模式几乎零成本。MaterialTheme 是文章 demo 里到处出现的外层包裹,本质就是给子树提供「主题环境」。
六、资深开发者的醍醐灌顶时刻
- Compose 的布局不是 ViewGroup 的翻版 。没有
onMeasure的多轮协商,测量是单遍的。这意味着自定义布局要自己实现测量逻辑 (第 11 篇),但也避免了 View 体系里MeasureSpec的坑。 Modifier是「不可变链」。每个 Modifier 都是一个包装对象,链式调用会生成嵌套结构。顺序决定嵌套层级,所以顺序即语义。padding在clickable前后,点击区域不同 :clickable在外层时,padding 区域也可点击;clickable在内层时,padding 区域不可点击。这是一个真实生产 bug 高发点。- 别滥用
Box做绝对定位 。优先用Column/Row+Arrangement/Alignment,语义更清晰,也更容易适配不同屏幕。
七、动手题
写一个「个人信息卡片」:头像圆形、姓名在右侧、下方一行简介,整体卡片有圆角、阴影、内边距。用 Row、Column、Box 和 Modifier 完成,特别注意 Modifier 顺序。
八、学习资料
- 官方《Layouts in Compose》:developer.android.com/develop/ui/...
- 官方《Modifiers》:developer.android.com/develop/ui/...
- Material 3 官方:m3.material.io
(下一篇预告:状态管理进阶,StateFlow + ViewModel 的工程级架构。)