返回博客

Jetpack Compose April 2026 Update 深度解读

2026 年 4 月,Jetpack Compose 发布了 BOM 2026.04.01,核心模块版本号攀升至 1.11。这是一次「分量十足」的月度更新:共享元素过渡终于有了真正的调试工具、触控板事件进入实验性 API、Testing v2 正式成为默认选择、Navigation 家族迎来稳健补丁和稳定里程碑,Compose Multiplatform 也在桌面端持续发力。

本文从 Android 开发者的角度,逐项拆解这次更新中最值得关注的变化。

📌 版本速览:Compose BOM 2026.04.01 | Core 1.11 | Compose Multiplatform 1.11.1 | Navigation3 1.1.1 | Navigationevent 1.1.0 | Webkit 1.16.0-rc01 | Lint 1.0.0-beta01

Overview:2026 年 Compose 的节奏

从 2025 年开始,Jetpack Compose 进入了「每月 BOM、季度大版本」的快速迭代周期。2026 年 4 月的 BOM 更新虽然不是季度大版本,但汇集了过去几个月积累的多项重要改进:从实验性 API 的完善(触控板、共享元素调试)到生产级工具的稳定化(Testing v2、Navigationevent),再到工具链的推进(Webkit RC、Lint Beta),覆盖了开发体验的方方面面。

从版本号的演进来看,Compose 1.11 标志着平台成熟度的进一步提升。相比 1.10 时代的主攻性能优化,1.11 更多聚焦在交互模式的扩展开发工具链的完善上。

Compose 1.11:核心运行时改进

Compose Runtime 和 UI 模块在 1.11 中获得了多项底层增强:

性能与稳定性

💡 迁移建议:如果你的项目目前使用 BOM 2025.12.01 或更早版本,1.11 的编译时间预期会略长于 1.10,因为新增的 lint 检查和代码生成增加了一些构建时开销,但运行时性能是正向收益。

共享元素过渡调试工具

共享元素过渡(Shared Element Transition)自 Compose 1.7 引入以来,一直是开发者又爱又恨的功能——效果华丽,但调试起来极其痛苦。在 1.11 中,Google 终于为它补上了缺失的工具链。

新工具能力

新的调试支持包含以下关键特性:

// 在 build.gradle.kts 中启用过渡调试
android {
    composeOptions {
        sharedElementTransitionDebug = true
    }
}

// 或者在运行时通过系统标志开启
adb shell setprop debug.compose.shared_element_transition true
📌 使用场景:如果你的应用使用了 SharedTransitionLayoutModifier.sharedElement() / Modifier.sharedBounds(),强烈建议在开发阶段开启调试模式。最常见的调试场景包括:列表到详情页的过渡错位、bounds 计算不准确导致的裁剪异常、以及多共享元素同时过渡时的时序冲突。

新增实验性 API

除了调试工具,1.11 还扩展了共享元素过渡的 API 能力:

// 新的实验性 API:精细控制共享元素的渲染阶段
@ExperimentalSharedElementApi
Modifier.sharedElement(
    state = sharedTransitionState,
    key = "avatar",
    renderMode = SharedElementRenderMode.ContentFirst
)

// 支持的渲染模式
enum class SharedElementRenderMode {
    ContentFirst,      // 优先渲染目标内容(默认行为)
    BoundsFirst,       // 优先对齐边界再变换内容
    Parallel           // 边界和内容同时变换
}

新的 SharedElementRenderMode 允许开发者控制过渡动画中「边界变换」和「内容变换」的执行顺序。对于包含圆角图片或复杂裁剪的共享元素,选择合适的渲染模式可以显著提升视觉平滑度。

触控板事件——桌面与 Web 的新交互模式

Compose 1.11 引入了一项新的实验性 API:触控板事件(Trackpad Events)。这虽然看起来是为 Desktop / Web 平台准备的,但对 Android 开发者同样有意义——尤其是那些正在或计划使用 Compose Multiplatform 构建跨平台应用的人。

为什么需要触控板事件

传统的 Compose 指针事件(pointerInput)是为触摸屏设计的:单指点击、滑动、长按。但触控板(Trackpad / Touchpad)的交互模式不同:它支持多指手势(双指缩放、三指滑动)、精确滚动(带 momentum)、压力感应等。如果没有原生支持,触控板在这些平台上只能模拟鼠标事件,体��大打折扣。

API 概览

@ExperimentalTrackpadApi
@Composable
fun TrackpadDemo() {
    var scale by remember { mutableFloatStateOf(1f) }
    var offset by remember { mutableStateOf(Offset.Zero) }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .trackpadInput(
                onScroll = { scrollDelta, sourceType ->
                    // 处理触控板滚动(带 momentum)
                    offset += scrollDelta
                },
                onGesture = { gesture ->
                    when (gesture) {
                        is TrackpadGesture.Pinch -> {
                            scale *= gesture.zoomFactor
                        }
                        is TrackpadGesture.Swipe -> {
                            // 三指/四指滑动
                        }
                    }
                }
            )
    ) {
        Image(
            painter = ...,
            contentDescription = null,
            modifier = Modifier
                .graphicsLayer {
                    scaleX = scale
                    scaleY = scale
                    translationX = offset.x
                    translationY = offset.y
                }
        )
    }
}

主要事件类型

事件描述适用场景
onScroll精确滚动,携带 momentum 和 sourceType(触摸板 vs 鼠标滚轮)列表滚动、画布平移
onGesture.Pinch双指捏合缩放图片/地图缩放
onGesture.Rotate双指旋转图片编辑器
onGesture.Swipe多指滑动页面切换、手势导航
onSecondaryClick双指轻点 / 右键上下文菜单
💡 跨平台开发者的福利:对于使用 Compose Multiplatform 构建桌面端应用的团队,触控板 API 意味着你的用户终于可以在 MacBook 触控板或 Windows Precision Touchpad 上获得原生级的操作体验。配合 FoundationGestures 中的 detectTransformGestures,可以构建丝滑的多点触控 + 触控板统一交互方案。

Testing v2 API 正式成为默认

这是本次更新中对开发者日常工作影响最直接的变化。Compose Testing v2 API 在经历多个版本的实验期后,终于在 1.11 中成为默认配置。

核心变化

最重要的变化是:StandardTestDispatcher 取代 UnconfinedTestDispatcher 成为默认测试调度器

方面v1(旧)v2(新默认)
测试调度器UnconfinedTestDispatcherStandardTestDispatcher
ComposeTestRulecreateComposeRule()createComposeRule()(已更新)
等待动画mainClock.autoAdvance = true默认 autoAdvance(同 v1 行为)
协程调度立即执行协程按序调度,更接近真实环境
Semantics 节点基本 API增强的 find/filter 能力
自定义 Matcher有限的扩展性更灵活的 Matcher 组合

迁移指南:从 Testing v1 到 v2

如果你的项目还在使用旧的 Compose Testing API,以下是需要修改的关键点:

1. 更新依赖

// 移除旧的测试依赖
// debugImplementation("androidx.compose.ui:ui-test-manifest")
// debugImplementation("androidx.compose.ui:ui-test-junit4")

// 启用 v2(BOM 2026.04.01 后默认)
android {
    composeOptions {
        useComposeTestingV2 = true // 旧项目需要显式设置
    }
}

// 测试依赖保持不变
debugImplementation("androidx.compose.ui:ui-test-manifest")
debugImplementation("androidx.compose.ui:ui-test-junit4")

2. 调整测试中的协程调度

// 旧:UnconfinedTestDispatcher——协程立即执行
@Test
fun oldApproach() {
    composeTestRule.setContent { ... }
    // 协程在 setContent 中立即执行完毕
}

// 新:StandardTestDispatcher——协程按序调度
@Test
fun newApproach() = runTest {
    composeTestRule.setContent { ... }
    // 协程不会立即执行,需要:
    composeTestRule.waitForIdle()        // 等待 compose 空闲
    // 或
    advanceUntilIdle()                    // 推进调度器直到空闲
}

3. 利用增强的 Semantics API

// Testing v2 增强的节点查找
composeTestRule
    .onAllNodes(
        hasTestTag("item")
            .and(hasText("Hello"))
            .and(isEnabled())
    )
    .assertCountEquals(3)

// 新的条件等待
composeTestRule.waitUntil(
    condition = { composeTestRule.onAllNodes(hasTestTag("loaded")).fetchSemanticsNodes().isNotEmpty() },
    timeoutMillis = 5000
)
⚠️ 迁移风险:如果你的测试中大量依赖「协程在 setContent 内立即执行完毕」的假设(UnconfinedTestDispatcher 的行为),切换到 StandardTestDispatcher 后可能会暴露一些竞态条件(race condition)。这不是 bug,而是你的测试之前过于乐观了。建议在迁移期间为每个测试文件添加 @RunWith(TestRunner::class),逐步替换非兼容测试。

为什么 Google 选择 StandardTestDispatcher

UnconfinedTestDispatcher 在 setContent 完成后立即执行所有协程,这在简单测试中很方便,但它掩盖了真实世界中协程调度的随机性。StandardTestDispatcher 按序调度协程,更能模拟真实运行环境,帮助开发者提前发现异步相关的 bug。这也是 Jetpack 整体测试策略的演进方向——此前 ViewModel 和 Room 的测试指南已经推荐使用 StandardTestDispatcher。

Navigation 更新:Navigation3 1.1.1 与 Navigationevent 1.1.0 稳定

Navigation 系列在 4 月获得了重要更新,包含两个关键版本:

Navigation3 1.1.1:稳健补丁

Navigation3(基于类型安全导航的新一代导航库)在 1.1.0 稳定版发布后迎来了第一个补丁版本,主要修复包括:

// Navigation3 典型用法(类型���全路由)
@Serializable
sealed class Route {
    @Serializable
    data class Home(val tab: String = "feed") : Route()
    
    @Serializable
    data class Article(val id: Long, val title: String) : Route()
    
    @Serializable
    data class Settings(val section: String? = null) : Route()
}

@Composable
fun AppNavigation() {
    val navController = rememberNavController3(
        startDestination = Route.Home()
    )
    
    NavHost3(navController = navController) {
        composable {
            HomeScreen(
                onArticleClick = { id, title ->
                    navController.navigate(Route.Article(id, title))
                }
            )
        }
        composable { backStackEntry ->
            val article = backStackEntry.toRoute()
            ArticleScreen(articleId = article.id, title = article.title)
        }
    }
}

Navigationevent 1.1.0:稳定里程碑

Navigationevent 库(用于监听和处理导航事件的工具库)在 4 月正式达到 1.1.0 稳定版。这个版本标志着导航事件追踪能力已足够成熟,可以用于生产环境。

💡 什么时候用 Navigationevent:如果你的应用需要精细的导航分析(如用户流失点分析、A/B 测试的路径追踪),或者需要将导航事件与业务指标关联,Navigationevent 1.1.0 提供了一个开箱即用且类型安全的解决方案。对于小型应用,直接监听 NavController.currentBackStackEntry 可能就足够了。

Webkit 1.16.0-rc01:Beta 到 RC

androidx.webkit 库从 Beta 推进到了 RC 阶段,发布了 1.16.0-rc01。对于在 Compose 中使用 AndroidView 集成 WebView 的场景,这个版本的更新包括:

从 Beta 到 RC 通常意味着功能已经冻结,下一个版本大概率是 1.16.0 稳定版。

Lint 1.0.0-beta01:Alpha 到 Beta

androidx.compose.lint 从 Alpha 晋升到了 Beta,版本号为 1.0.0-beta01。这是 Compose 专用 Lint 检查器走向稳定的重要一步。

新增检查规则

规则名作用严重级别
ComposeUnstableReceiver检测 Composable lambda 中使用了不稳定的接收者类型Error
ComposeModifierReusing检测 Modifier 是否在重组中被正确复用Warning
ComposeContentScaleUsage检测 Image 组件是否正确设置了 contentScaleWarning
ComposeNavigationTypeSafety检测 Navigation3 路由参数的类型安全性Error
ComposeSharedElementUsage检测共享元素过渡的常见误用模式Warning

其中 ComposeNavigationTypeSafetyComposeSharedElementUsage 是 1.0.0-beta01 新增的规则。前者可以在编译阶段就发现 Navigation3 路由参数类型不匹配的问题,后者帮助开发者避免共享元素过渡的常见陷阱(如 key 重复、父容器缺少 SharedTransitionLayout 等)。

📌 如何在项目中启用:Compose Lint 检查默认集成在 AGP 的 lint 检查中。使用最新 BOM 后,IDE 和构建时会自动应用这些检查规则。你也可以通过 lintOptions 配置检查的严重级别。

Compose Multiplatform 1.11.1

JetBrains 在 4 月同步发布了 Compose Multiplatform 1.11.1,与 Jetpack Compose 1.11 保持核心同步。这次更新的亮点集中在桌面端能力的提升上。

关键更新

// Compose Multiplatform 1.11.1 的摄像头 API 示例(桌面端)
@Composable
fun CameraPreview() {
    val cameraManager = rememberCameraManager()
    val camera = cameraManager.getCamera()
    
    DisposableEffect(camera) {
        camera.start()
        onDispose { camera.stop() }
    }
    
    AndroidView(
        factory = { context ->
            SurfaceView(context).apply {
                camera.setPreviewDisplay(holder)
            }
        }
    )
}
💡 跨平台实践:如果你同时在 Android 和 Desktop 上使用 Compose Multiplatform,建议将平台特定逻辑(摄像头、窗口管理)放在 expect/actual 声明中,共享 UI 部分则用 commonMain 中的纯 Compose 组件。1.11.1 中窗口管理的改进使得 expect/actual 的边界更加清晰。

Material3 Adaptive:还在 Alpha

虽然 Material3 Adaptive 库在本轮更新中仍然处于 Alpha 阶段,但它获得了新的构建版本,带来了以下改进:

对于计划适配大屏(平板、可折叠设备)的应用,可以浏览 Google 的自适应布局指南了解 Material3 Adaptive 的使用路径。

实战迁移检查清单

如果你计划升级到 Compose BOM 2026.04.01(或之后的 BOM),以下是一份实用的迁移检查清单:

⬜ Compose BOM 升级
更新 build.gradle.kts 中的 compose-bom 版本为 2026.04.01
// build.gradle.kts
dependencies {
    val composeBom = platform("androidx.compose:compose-bom:2026.04.01")
    implementation(composeBom)
    implementation("androidx.compose.ui:ui")
    implementation("androidx.compose.material3:material3")
    // ...
}
⬜ Testing v2 迁移
检查所有 Compose 测试文件,将 createComposeRule() 的测试迁至 StandardTestDispatcher 语义。添加 composeOptions.useComposeTestingV2 = true(如未默认启用)。增加 waitForIdle() / advanceUntilIdle() 调用。
⬜ Navigation3 升级
更新 androidx.navigation:navigation-compose 到 2.9+(含 Navigation3 1.1.1)。检查深层链接和返回栈逻辑。评估是否需要引入 navigationevent 1.1.0。
⬜ 共享元素过渡调试
在开发 flavor 中启用 sharedElementTransitionDebug 标志。运行共享元素过渡的 UI 测试,使用新的调试工具排查动画问题。尝试新的 SharedElementRenderMode API 优化视觉效果。
⬜ Compose Lint 检查
运行 ./gradlew lint,检查是否有新的警告和错误。重点关注 ComposeNavigationTypeSafetyComposeSharedElementUsage 规则。
⬜ 跨平台评估
如果你在使用 Compose Multiplatform,评估 1.11.1 的 Shader Navigation、Hinge 和 Desktop Camera API 是否对你的项目有价值。

总结

Jetpack Compose April 2026 Update(BOM 2026.04.01)是一份「厚积薄发」的月度更新。它没有带来革命性的新概念,但在以下四个维度上让 Compose 生态成熟了一大步:

  1. 开发工具链——共享元素过渡调试工具和 Compose Lint 的 Beta 晋升,让「写 Compose」变得更安心
  2. 测试基础设施——Testing v2 成为默认方案,虽然迁移需要一些功夫,但长期来看会让测试更加可靠
  3. 交互模式扩展——触控板事件为 Desktop/Web 平台打开了新的交互维度,跨平台应用的用户体验将再上一个台阶
  4. 生态成熟度——Navigationevent 稳定、Webkit RC、Lint Beta、Material3 Adaptive 持续迭代,都表明 Compose 生态正在全面走向生产就绪

对于 Android 开发者,这次更新最直接的行动点就是:升级 BOM、迁移 Testing v2、打开共享元素调试。前两者是生产环境的硬要求,后者是开发体验的明显提升。

Compose 的进化从未停止。从 1.0 到 1.11,我们见证了 Android UI 开发从 View 系统到声明式范式的完整迁移。而 2026 年的 Compose,已经做好了迎接多平台时代的准备。