Jetpack Compose — Google为Android开发打造的现代声明式UI框架,于2021年7月发布稳定版1.0。Compose用带有@Composable注解的Kotlin函数替代了命令式XML标记和View系统。根据Google I/O(2025)数据,Compose在55%的新Android项目中使用,UI代码平均大小相比XML减少30–50%。框架在State变化时自动仅重绘屏幕变化部分,无需手动调用notifyDataSetChanged或findViewById。
要点
Jetpack Compose — Google基于反应式编程原理构建的UI框架。开发者通过带有@Composable注解的Kotlin函数描述界面,而非使用带有XML布局的Activity、FragmentManager和ViewBinding。Compose不使用LayoutInflater — UI是纯Kotlin函数,编译为字节码。框架由多个库组成:Compose UI(基础组件Text、Button、Column、Row)、Compose Foundation(Material Design、手势、焦点)、Compose Material3(带Dynamic Colors的Material You)和Compose Runtime(State、Side Effects、Coroutines)。Compose运行于Android API 21+(Android 5.0),并通过ComposeView(AndroidView适配器)与现有View/XML代码完全兼容。
View System(2008)使用带有手动管理的View对象层次结构:开发者创建XML布局,通过findViewById查找View,为RecyclerView实现Adapter,并在数据变化时调用notifyDataSetChanged。Compose函数式地描述UI:状态变化时,框架仅重新启动(recompose)变化的Composable函数,计算差异并将最小更改应用于Canvas。Compose的性能与View System相当,在复杂列表(LazyColumn)场景中,通过key参数跳过不必要元素,常常优于RecyclerView。在IT Sectr,Compose用于minSdk 24+的Android应用程序新模块。
@Composable — 将普通Kotlin函数转换为UI构建块的注解。Composable函数可以调用其他Composable函数,形成组件树。与View不同,Composable函数默认没有状态——它们是stateless的,并在每次输入参数或State变化时重新绘制。编译器(Compose Compiler)将@Composable函数转换为可中断和恢复的代码(positional memoization)——这使得Compose无需完全重建树即可重新启动仅变化的部分。
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
@Composable
fun UserProfile(name: String, avatarUrl: String) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
AsyncImage(
model = avatarUrl,
contentDescription = "User avatar",
modifier = Modifier.size(48.dp)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = name,
style = MaterialTheme.typography.titleMedium
)
}
}UserProfile函数接受name和avatarUrl作为参数,构建包含头像和名称的行。Modifier.fillMaxWidth()将组件拉伸到全宽,.padding(16.dp)添加间距。MaterialTheme.typography.titleMedium使用Material 3系统样式。当name或avatarUrl参数变化时,Compose重新启动UserProfile——用新值重新创建组件。
State在Compose中——任何变化会导致依赖的@Composable函数重组(重新启动)的值。基本方式是mutableStateOf(),创建带有Compose快照系统支持的MutableState<T>。Snapshot——跟踪变化的机制:写入State时,Compose将当前Snapshot标记为脏,重组调度器仅重新启动读取该State的Composable函数。对于可观察集合,使用mutableStateListOf()和mutableStateMapOf()。Compose通过collectAsState()(用于Kotlin Flow)和observeAsState()(用于LiveData)支持来自Lifecycle-Aware组件的State。
@Composable
fun LikeButton() {
var liked by remember { mutableStateOf(false) }
var count by remember { mutableStateOf(42) }
Button(
onClick = {
liked = !liked
if (liked) count++ else count--
},
colors = ButtonDefaults.buttonColors(
containerColor = if (liked) MaterialTheme.colorScheme.primary
else MaterialTheme.colorScheme.surfaceVariant
)
) {
Text("♥ $count")
}
}代码创建了一个带有liked(Boolean)和count(Int)状态的「Like」按钮,通过mutableStateOf()存储。点击时,liked反转,计数器增加/减少——Compose自动重新启动LikeButton。by委托允许像普通变量一样使用State:liked = !liked而不是liked.value = !liked.value。按钮颜色在primary(已赞)和surfaceVariant(未赞)之间反应式变化。
remember — 在重组之间缓存值的Compose函数。没有remember,每次重启Composable函数都会创建新状态(mutableStateOf)——这会破坏应用程序逻辑:屏幕旋转或父State变化时,计数器将重置。remember接受计算器lambda,仅在首次组合时计算值;后续返回缓存结果。要重置缓存,使用remember(key)——键确定何时重新计算值。remember(key1, key2)在任一键变化时重新计算。对于长生命周期状态(能承受屏幕旋转),使用rememberSaveable——通过SavedStateHandle在Bundle中保存的remember类似物。
@Composable
fun TimerScreen() {
var seconds by rememberSaveable { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
seconds++
}
}
Column(
modifier = Modifier.fillMaxSize().padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "已过时间:${seconds}s",
style = MaterialTheme.typography.displayMedium
)
}
}rememberSaveable在屏幕旋转(配置变化)时保持seconds。LaunchedEffect启动一个协程,每秒增加seconds。在TimerScreen重组(每秒)时,由于rememberSaveable,seconds不会重置。对于不应承受配置变化的状态(例如动画标志),使用普通的remember。
Modifier — 不可变容器对象,实现Builder模式用于设置Composable组件的外观、行为和布局。每次调用Modifier方法(.padding()、.width()、.clickable()、.background())都会返回一个添加了新元素的新Modifier。修饰符顺序很重要:.padding(16.dp).clickable { }——间距在点击处理程序之前应用,clickable考虑间距跟踪整个区域。.clickable { }.padding(16.dp)——间距之前的整个区域可点击,间距将内容向内移动。Modifier通过then(otherModifier)支持自定义实现,通过compositionLocal访问父级设置。
@Composable
fun CardExample() {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable { println("卡片已点击") },
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text("Jetpack Compose", style = MaterialTheme.typography.titleLarge)
Spacer(modifier = Modifier.height(8.dp))
Text(
"使用State和Modifier的Android声明式UI",
style = MaterialTheme.typography.bodyMedium
)
}
}
}CardExample演示了Modifier链:fillMaxWidth + padding + clickable。Card — 带有自定义elevation和colors设置的Material3组件。嵌套的Column具有16dp的内边距。Compose Material3在Android 12+上自动将颜色适配到Dynamic Color(Material You)。Card是Compose中30多个内置Material3组件之一。
State hoisting — 从Composable函数向其调用者提升状态的模式,使函数变为stateless。Stateless组件通过参数接收数据和回调,不拥有自己的State。这提高了可重用性和可测试性:可以用不同State调用组件并在预览中测试。Google推荐架构:ViewModel + StateFlow(或MutableStateFlow)+ Compose中的collectAsState()。ViewModel将状态提升到屏幕级别,Compose显示。副作用(LaunchedEffect、DisposableEffect)处理一次性事件。
| 组件 | 职责 | 技术 |
|---|---|---|
| ViewModel | 存储State,业务逻辑 | StateFlow, MutableStateFlow |
| Screen Composable | 屏幕组织,State hoisting | collectAsState(), Scaffold, LazyColumn |
| Stateless Component | 无状态UI,纯显示 | @Composable参数 + lambda |
| Side Effect | 一次性操作(snackbar,导航) | LaunchedEffect, SnackbarHostState |
常见问题
XML布局是命令式的:LayoutInflater加载XML,findViewById查找View,开发者手动更新文本/列表。Compose是声明式的:UI通过Kotlin @Composable函数描述,框架在State变化时自动仅重绘变化的部分。Compose减少UI代码量30–50%且不使用XML。
是的,Google提供了Navigation Compose——用于在屏幕之间进行声明式导航的库。NavController管理路由栈,composable()注册屏幕,navArgument传递参数。替代方案:Voyager(社区)和Decompose(Badoo)。Navigation Compose是官方标准,支持deep links和type-safe参数。
Modifier — 应用于Composable组件的样式模式的不可变容器(padding、size、clickable、background、border、clip)。每次调用返回添加了新元素的新Modifier。顺序很重要:.padding().clickable()在点击前应用间距,.clickable().padding()则相反。Modifier是自定义Compose组件的主要方式。
Jetpack Compose通过Compose Compiler和Compose BOM支持Android API 21+(Android 5.0 Lollipop)。Material 3(Dynamic Colors)在Android 12+上可用;较旧版本使用回退调色板。对于新项目,Apple建议minSdk 24+(Android 7.0),Compose完全覆盖。
Google提供Compose UI Test——用于在JVM(桌面)和模拟器上测试的库。主要功能:composeTestRule.setContent { }渲染组件,onNodeWithText()搜索元素,performClick()/performTextInput()进行操作。Espresso测试通过ComposeTestRule与Compose兼容,但Compose UI Test是更优且更快的方案。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。