Jetpack Compose 声明式 UI 入门
Jetpack Compose 声明式 UI 入门
摘要:Jetpack Compose 是 Android 官方推出的现代声明式 UI 工具包,使用 Kotlin 构建,能显著减少 UI 代码量并提升可维护性。本文从核心概念出发,逐步讲解可组合函数、状态管理、布局与主题,帮助你快速上手。
一、为什么选择 Compose
传统 Android UI 开发使用 XML 布局 + View 体系,存在以下痛点:
- 命令式更新:手动调用
findViewById、setText、setVisibility,状态与视图容易脱节。 - 复用困难:自定义 View 门槛高,include/merge 语义有限。
- 双向同步:数据变化要刷新 View,View 变化要回写数据,样板代码多。
Compose 采用声明式范式:你描述 UI 在不同状态下的样子,框架负责在状态变化时自动重新执行并更新界面。好处是:
- 代码量通常减少 30%~50%。
- 状态单一来源,不易出现不一致。
- Kotlin 一等公民,条件、循环直接写,无需 XML。
- 强类型预览(
@Preview)让设计调试更高效。
二、核心概念
1. 可组合函数
被 @Composable 注解的函数,是 Compose 的基本构建块:
@Composable
fun Greeting(name: String) {
Text(text = "你好,$name")
}
要点:
- 只能在另一个
@Composable函数内调用其他 Composable。 - 函数本身应该是无副作用的纯描述(状态读取除外)。
- 命名习惯使用 PascalCase。
2. 状态与重组
remember 把对象保存在组合中,mutableStateOf 创建可观察状态:
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("点击了 $count 次")
}
}
当 count 变化时,Counter 会重组,Text 会刷新。Compose 会尽可能只重组受影响的部分。
3. 状态提升
把状态从子组件"提升"到父组件,让子组件变成无状态纯函数,便于复用与测试:
@Composable
fun StatelessCounter(count: Int, onIncrement: () -> Unit) {
Button(onClick = onIncrement) {
Text("点击了 $count 次")
}
}
@Composable
fun CounterHost() {
var count by remember { mutableStateOf(0) }
StatelessCounter(count = count, onIncrement = { count++ })
}
三、常用布局
Column 与 Row
Column(
modifier = Modifier.fillMaxSize().padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text("第一行")
Text("第二行")
Text("第三行")
}
Row 用法类似,控制水平排列。Arrangement.spacedBy 提供均匀间距。
Box
层叠布局,子元素默认左上对齐,可通过 Alignment 调整:
Box(modifier = Modifier.size(120.dp), contentAlignment = Alignment.Center) {
Image(painter = ..., contentDescription = null)
Text("覆盖文字", color = Color.White)
}
LazyColumn
长列表的高效实现,相当于 RecyclerView:
LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) {
items(items = dataList) { item ->
ItemRow(item)
}
}
只重组可见项,性能优秀。
四、Modifier 链式修饰
Modifier 是配置节点的核心 API,顺序敏感:
Modifier
.fillMaxWidth()
.padding(12.dp)
.background(Color(0xFF1A1A1A))
.clip(RoundedCornerShape(8.dp))
注意:padding 在 background 之前,内边距会有背景色;之后则不会。顺序决定了视觉效果。
五、主题与 Material3
使用 MaterialTheme 统一颜色、字体、形状:
MaterialTheme(
colorScheme = darkColorScheme(primary = Color(0xFFD4A84B)),
typography = Typography(
headlineLarge = TextStyle(fontSize = 28.sp, fontWeight = FontWeight.Bold)
)
) {
Surface(modifier = Modifier.fillMaxSize()) {
AppContent()
}
}
取用主题值:
val primary = MaterialTheme.colorScheme.primary
val headline = MaterialTheme.typography.headlineLarge
六、预览
@Preview 让你在 IDE 中直接看到 UI,无需运行:
@Preview(name = "默认状态", showBackground = true)
@Composable
fun GreetingPreview() {
MaterialTheme {
Greeting(name = "北京")
}
}
可写多个 Preview 覆盖深色模式、不同字体缩放、多语言。
七、与现有代码互操作
Compose 中使用 View
AndroidView(factory = { context ->
MapView(context).apply {
onCreate(null)
getMapAsync { map -> map.moveCamera(...) }
}
})
View 体系中嵌入 Compose
class ComposeViewBridge : LinearLayout(context) {
init {
val composeView = ComposeView(context).apply {
setContent {
MaterialTheme { Greeting("Android") }
}
}
addView(composeView)
}
}
八、性能要点
- 用
key标记列表项身份,避免不必要的重组。 - 用
derivedStateOf缓存派生状态,减少重组范围。 - 避免在 Composable 中创建昂贵对象,交给
remember。 - 使用
stable注解或不可变集合,帮助 Compose 跳过相等比较。 - 开发期开启
Modifier.composable重组高亮,定位性能热点。
九、总结
Jetpack Compose 用声明式思维重新定义了 Android UI 开发。掌握可组合函数、状态、布局、主题四块就能完成绝大多数界面;再配合预览与性能技巧,可以构建出既简洁又高效的应用。建议从新页面开始试点,逐步迁移老代码,体验声明式带来的开发效率提升。
- 点赞
- 收藏
- 关注作者
评论(0)