移动开发中的 Jetpack Compose:它是什么、核心概念以及工作原理

作者: IT Sectr 发布日期: 2026-07-05 阅读时间: 10 分钟
Jetpack Compose — 来自 Google 的现代 Android UI 框架。根据 Google Compose Docs (2025),Compose 被用于 60% 的新 Android 项目。理解 @Composable、Recomposition 和 State Hoisting 是高效使用 Compose 的基础。

要点

  • @Composable — UI 函数的注解。Composition — 调用 Composable 函数。Recomposition — 状态改变时重新启动。
  • State Hoisting — 将状态提升到父组件。State down, events up。可重用和可测试的组件。
  • remember + mutableStateOf — 本地状态。remember 在重组之间保留值。
  • Modifier — 修饰符链(padding, size, clickable)。顺序很重要。
  • NavController + NavHost — 导航。LaunchedEffect/DisposableEffect — 副作用。

Jetpack Compose 基础 (@Composable, Composition, Recomposition)

@Composable — 将函数转换为 Composable 的注解。Composable 函数是 UI 的构建块。它们不返回 View,而是将元素发射到 Composition 中。Composition — 由 Composable 函数调用构建的 UI 树。Compose 比较新树和旧树,只更新发生变化的部分。

Recomposition

Recomposition — 状态改变时重新启动 Composable 函数。Compose 跟踪每个函数中读取的状态。当状态改变时,Compose 只重新启动读取该状态的函数(智能重组)。重组是乐观的:可能运行多次,因此函数必须是纯函数(无副作用)。副作用放在 LaunchedEffect 或 DisposableEffect 中。Composable 函数不能是 suspend。它们从其他 Composable 函数调用。调用顺序不保证(Compose 可以重新排序)。

kotlin
// 带有 State Hoisting 和 LazyColumn 的 Composable 示例
@Composable
fun ItemList(
    items: List<String>,
    onItemClick: (String) -> Unit
) {
    LazyColumn(
        modifier = Modifier.fillMaxSize()
    ) {
        items(items) { item ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { onItemClick(item) }
                    .padding(8.dp)
            ) {
                Text(
                    text = item,
                    style = MaterialTheme.typography.bodyLarge
                )
            }
        }
    }
}

@Composable
fun MainScreen() {
    var text by remember { mutableStateOf("") }
    val items = listOf("Item 1", "Item 2", "Item 3")

    Scaffold(
        topBar = {
            TopAppBar(title = { Text("Compose App") })
        }
    ) { padding ->
        ItemList(
            items = items,
            onItemClick = { selected -> text = selected }
        )
    }
}

Composition — 声明式树。Recomposition — 智能重启。IT Sectr 建议监控类型稳定性 — 不稳定的类型会导致过度重组。

CompositionLocal

CompositionLocal — Compose 中的隐式数据传递。类似于 SwiftUI 中的 @Environment。CompositionLocalProvider — 设置值。current — 读取。用于:Theme (MaterialTheme), ContentScale, Density。静态 CompositionLocal — 用于不变的配置。动态 CompositionLocal — 用于可变值(主题)。IT Sectr 建议对全局配置使用 CompositionLocal,对数据使用显式参数。

状态 (remember, mutableStateOf, State Hoisting)

remember — 在重组之间保留值。mutableStateOf — 创建可观察状态 (MutableState<T>)。更改时触发重组。State Hoisting — 模式:状态提升到父组件,子组件接收值 + 回调。State(不可变)— 只读。MutableState — 读写。rememberSaveable — 在旋转/进程终止时保持。

State Hoisting

State Hoisting — 原则:state down, events up。状态存储在父组件中,通过参数传递给子组件。子组件通过 lambda(回调)报告更改。优点:可重用性、可测试性、单一真实来源。示例:不是让 MyTextField 存储自己的状态,而是由父组件存储字符串并通过 value + onValueChange 传递。

派生状态

derivedStateOf — 计算状态,仅在依赖项更改时重新计算。用于过滤、转换、验证。snapshotFlow — 将 State 转换为 Flow。用于响应式链。collectAsState — 在 Composable 内将 Flow 收集到 State。IT Sectr 建议对计算值使用 derivedStateOf,对将 State 连接到协程使用 snapshotFlow。

容器 (Column, Row, Box, LazyColumn)

Column — 垂直布局(类似于 LinearLayout 垂直)。Row — 水平布局。Box — 堆叠布局(类似于 FrameLayout)。LazyColumn — 带延迟加载的垂直可滚动列表。LazyRow — 水平可滚动列表。Scaffold — 主要屏幕结构:TopAppBar, BottomBar, FloatingActionButton, Snackbar。TopAppBar — 顶部栏。BottomNavigation — 底部导航(Material 3 中的 NavigationBar)。Modifier — 链:.fillMaxWidth().padding(8.dp).clickable { }。修饰符顺序很重要 — 每个修饰符创建一个新的包装器。

LazyColumn 优化

LazyColumn — 虚拟化列表。仅渲染可见元素。优化:1) key — 项目的唯一键,2) contentType — 按类型分组项目,3) itemContent — 最小化项目内部的重组,4) LazyVerticalGrid / LazyHorizontalGrid — 用于网格。LazyLayout — 自定义延迟布局。Paging 3 + Compose — 通过 collectAsLazyPagingItems 分页。IT Sectr 建议对所有 LazyColumn 使用 key(item) 以实现可预测的重组。

Navigation Compose — 导航库。NavController — 管理目标堆栈。NavHost — 导航图的容器。composable("route") — 注册目标。navController.navigate("route") — 导航。popBackStack() — 返回。参数:composable("detail/{id}", arguments = listOf(navArgument("id") { type = NavType.StringType }))。通过 intentFilter 进行深度链接。BottomNavigation — 与 NavController 集成:NavBarItem → navigate + popUpTo。

多个返回堆栈 — 每个 BottomNavigation 选项卡有独立的返回堆栈。SavedStateHandle — 在进程终止时保留参数。NavArgs — 类型安全参数 (Kotlin 2.0+)。深度链接 — 外部链接的 URL 方案。预测性返回手势 (Android 14+) — 支持带预览的返回手势。IT Sectr 建议使用 NavArgs 实现类型安全,对 BottomNavigation 使用多个返回堆栈。

效果 (LaunchedEffect, DisposableEffect)

LaunchedEffect — 在 Composition 中启动 suspend 块。离开 Composition 时取消。keys 更改时重新启动。用于:数据加载、计时器、动画。DisposableEffect — 用于需要清理的资源:onDispose { } — 取消订阅监听器、关闭连接。SideEffect — 同步效果(每次重组)。用于:日志记录、与非 Compose 代码同步。IT Sectr 建议使用 LaunchedEffect 加载数据,使用 DisposableEffect 进行清理。

参数 Jetpack Compose SwiftUI
UI 描述@Composable 函数 + ModifierView Protocol + @ViewBuilder
状态remember + mutableStateOf@State, @StateObject
状态提升State Hoisting@Binding
列表LazyColumnList
导航NavController + NavHostNavigationStack (iOS 16+)
效果LaunchedEffect, DisposableEffect.task{}, .onAppear{}
布局Column, Row, BoxVStack, HStack, ZStack

Compose — 函数 + 修饰符。SwiftUI — struct + 修饰符。概念相似,语法不同。IT Sectr 建议学习两个框架 — 理解一个有助于学习另一个。

效果模式

rememberCoroutineScope — 在 LaunchedEffect 外部访问 CoroutineScope(例如,按钮点击时)。snapshotFlow — 将 State 转换为 Flow 用于链式操作。produceState — 将非 Compose 源转换为 State。animateFloatAsStateanimateColorAsState — 通过效果实现动画。IT Sectr 建议对 UI 事件使用 rememberCoroutineScope,对自动加载使用 LaunchedEffect。

主题 (MaterialTheme, Material3)

MaterialTheme — Compose 的全局主题。颜色、排版、形状。MaterialTheme { } — 包装整个应用。Material3 (M3) — Google 设计系统 2023+。Dynamic Colors — 适应壁纸 (Android 12+)。TextStyle — 文本配置:fontSize, fontWeight, lineHeight。Shape — 圆角。Elevation — 阴影。IT Sectr 建议默认使用 Material3,现代设备使用 Dynamic Colors。

kotlin
@Composable
fun AppTheme(content: @Composable () -> Unit) {
    val colorScheme = if (isSystemInDarkTheme()) {
        darkColorScheme(
            primary = Color(0xFFBB86FC),
            secondary = Color(0xFF03DAC6)
        )
    } else {
        lightColorScheme(
            primary = Color(0xFF6200EE),
            secondary = Color(0xFF03DAC6)
        )
    }
    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography(
            bodyLarge = TextStyle(fontSize = 16.sp)
        )
    ) { content() }
}

动画 (animate*, AnimatedVisibility)

animateFloatAsState — 动画化 Float 值。animateColorAsState — 动画化颜色。animateDpAsState — 动画化大小。AnimatedVisibility — 使用 .animateEnterExit() 显示/隐藏。AnimatedContent — 内容更改时的动画 (crossfade, slide)。updateTransition — 基于枚举状态的动画。Animatable — 通过 Animatable 接口实现自定义动画。IT Sectr 建议对列表使用 AnimatedVisibility,对屏幕过渡使用 AnimatedContent。

kotlin
@Composable
fun AnimatedCounter(count: Int) {
    val animatedCount by animateFloatAsState(
        targetValue = count.toFloat(),
        animationSpec = spring(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        )
    )

    AnimatedContent(targetState = count) { targetCount ->
        Text(
            text = "$targetCount",
            style = MaterialTheme.typography.displayLarge,
            modifier = Modifier.animateContentSize()
        )
    }
}

测试 (Compose UI Test)

Compose UI Test — Compose 屏幕的测试。createComposeRule() — JUnit 规则。setContent { } — 设置 Composable。onNodeWithText, onNodeWithTag, onNodeWithContentDescription — 查找元素。performClick, performTextInput, performScrollTo — 操作。assertIsDisplayed, assertTextEquals — 断言。Semantics — 用于可访问性和测试的 Semantics 树。IdlingResource — 等待异步操作。截图测试 — Papercuts, Roborazzi。IT Sectr 建议对每个屏幕进行 UI 测试,对 ViewModel 进行单元测试。

WindowSizeClass — 适应屏幕大小 (Compact, Medium, Expanded)。与 Material3 响应式布局相关。在 Adaptive Navigation Suite 中用于自动从 BottomNavigation 切换到 NavigationRail。IT Sectr 建议对平板电脑和桌面 Compose 适配使用 WindowSizeClass。

Paging 3 + Compose — Google 的分页库。PagingData — 页面流。PagingConfig — 设置 (pageSize, prefetchDistance)。collectAsLazyPagingItems() — 在 Compose 中收集。PagingSource — 自定义源。RemoteMediator — 混合加载(网络 + 数据库)。Paging 3 是 Compose 中无限滚动列表的标准。

常见问题

Jetpack Compose 中的 @Composable 是什么?

@Composable — UI 函数的注解。Composable 函数调用形成 Composition。Recomposition — 状态改变时重新启动。

Compose 中的 State Hoisting 是什么?

State Hoisting — 将状态提升到父组件。State down, events up。可重用和可测试的组件。

Jetpack Compose 中的 Recomposition 是什么?

Recomposition — 状态改变时重新启动 Composable 函数。Smart Recomposition — 最小函数集。

NavController 和 NavHost 如何工作?

NavController — 目标堆栈。NavHost — 图容器。composable("route") — 注册。navigate() — 过渡。

LaunchedEffect 和 DisposableEffect 有什么区别?

LaunchedEffect — 带自动取消的 suspend 块。DisposableEffect — 带 onDispose 清理的资源。

总结

  • @Composable — UI 函数。Composition — UI 树。Recomposition — 智能重启。
  • remember + mutableStateOf — 本地状态。rememberSaveable — 用于旋转。
  • State Hoisting — state down, events up。可重用组件的基础。
  • Modifier — 链(顺序重要)。Column, Row, Box — 基本容器。
  • LazyColumn — 高效列表。Scaffold — 屏幕结构 (TopBar, BottomBar, FAB)。
  • NavController + NavHost — 导航。composable() — 路由。navigate() — 过渡。
  • LaunchedEffect — 异步效果。DisposableEffect — 清理。SideEffect — 同步。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目