为什么选择 Jetpack Compose
Jetpack Compose 是 Google 官方的声明式 UI 工具包,用 Kotlin 写界面,替代传统的 XML 布局。核心区别:
| 传统 View 体系 |
Jetpack Compose |
| XML 写布局 |
纯 Kotlin 声明 UI |
数据变化手动 findViewById 更新 |
状态变化 UI 自动重组 |
| 命令式(告诉系统”怎么改”) |
声明式(告诉系统”长什么样”) |
一、创建项目
打开 Android Studio,选择 New Project → Empty Activity,语言选 Kotlin,最低 SDK 建议 API 24+。新版 Android Studio 会自动引入 Compose 依赖。
关键依赖(app/build.gradle.kts):
1 2 3 4 5 6
| dependencies { implementation(platform("androidx.compose:compose-bom:2024.09.03")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.material3:material3") implementation("androidx.activity:activity-compose:1.9.2") }
|
二、第一个 Composable 页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.example.myapp
import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MyApp() } } }
@Composable fun MyApp() { MaterialTheme { GreetingScreen() } }
@Composable fun GreetingScreen() { var count by remember { mutableStateOf(0) }
Column( modifier = Modifier .fillMaxSize() .padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "点击次数:$count", style = MaterialTheme.typography.headlineMedium ) Spacer(modifier = Modifier.height(16.dp)) Button(onClick = { count++ }) { Text("点我") } } }
|
几个关键点:
@Composable 标记可组合函数,UI 全由这些函数组成;
remember { mutableStateOf(...) } 是 Compose 的状态管理核心,状态变了,使用它的 UI 自动重组;
Column / Row / Box 是三大布局容器,Modifier 链式设置尺寸、边距、对齐。
三、状态提升与回调
子组件不应持有全局状态,把状态”提升”到父组件,通过参数 + 回调传递:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Composable fun CounterScreen() { var count by remember { mutableStateOf(0) }
Column(horizontalAlignment = Alignment.CenterHorizontally) { CounterDisplay(count = count) CounterButton(onIncrement = { count++ }) } }
@Composable fun CounterDisplay(count: Int) { Text("当前值:$count", style = MaterialTheme.typography.titleLarge) }
@Composable fun CounterButton(onIncrement: () -> Unit) { Button(onClick = onIncrement) { Text("+1") } }
|
四、列表:LazyColumn
列表用 LazyColumn(对应 RecyclerView),只渲染可见项,性能好:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Composable fun TodoList(todos: List<String>) { LazyColumn( modifier = Modifier.fillMaxSize(), contentPadding = PaddingValues(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp) ) { items(todos.size) { index -> Card(modifier = Modifier.fillMaxWidth()) { Text( text = todos[index], modifier = Modifier.padding(16.dp) ) } } } }
|
items 也支持 items(todos) 传数据列表,配合 key 参数提供稳定 id:
1 2 3
| items(items = todos, key = { it.id }) { todo -> TodoItem(todo) }
|
五、主题配置
Compose 的主题基于 MaterialTheme 的三个维度:colorScheme、typography、shapes。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| private val LightColors = lightColorScheme( primary = Color(0xFF3F51B5), secondary = Color(0xFFFF9800) )
private val DarkColors = darkColorScheme( primary = Color(0xFF7986CB) )
@Composable fun MyAppTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colorScheme = if (darkTheme) DarkColors else LightColors, typography = Typography(), content = content ) }
|
isSystemInDarkTheme() 自动跟随系统深色模式。
六、@Preview 实时预览
Compose 支持不跑模拟器直接在 IDE 里预览:
1 2 3 4 5 6 7
| @Preview(showBackground = true, showSystemUi = true) @Composable fun GreetingScreenPreview() { MyAppTheme { GreetingScreen() } }
|
常见坑
remember 与 rememberSaveable:旋转屏幕后 remember 状态会丢,需要跨配置保留时用 rememberSaveable;
- 重组范围过大:尽量把状态往下传、把不变的 Composable 用
Modifier 或其他手段隔离,减少不必要的重组;
- 协程:异步操作在
LaunchedEffect 里做,不要直接在 Composable 里 Thread.sleep 之类的阻塞操作。
总结
Compose 的核心思维转变是”状态驱动 UI”:先声明状态,再声明状态到 UI 的映射。熟练掌握 remember + mutableStateOf、LazyColumn、状态提升这三板斧,就能开始写业务页面了。下一步可以学 Navigation 导航和 ViewModel 架构组件。