
Jetpack Compose 2026 年 8 月版本现已稳定发布。
这次核心 Compose 模块都来到了 1.12:
makefile
androidx.compose.runtime:runtime:1.12.0
这次新增了不少能力:Mesh Gradient、广色域(WCG)支持、Grid 的命名区域、与 Android Credential Manager 的集成,以及测试和性能方面的改进。
如果要升级到这个版本,只需要把项目里的 compose-bom 更新为 2026.08.00:
kotlin
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
破坏性变更
AGP 与 Compile SDK: Compose 1.12 将 compileSdk 提升到了 API 37,最低需要 AGP 9.1.1。Compose 会始终以最新的 compileSdk 为目标版本构建。
虽然 AI Coding 的时代这些可能没有那么重要了,但是我依然要吐槽一下 Android 这个升级------一点兼容性没有,像这次提升到 API 37,基本上等同于 AGP,Kotlin,Android Studio 都要一并更新,牵一发而动全身。有时候我甚至觉得只有搞 Android 的老手才能搞明白这些。
Modifier.onFirstVisible() 已被弃用。需要迁移到 Modifier.onVisibilityChanged(),后者可以更精确地跟踪可见性阈值。
并且,如果你使用到了 Styles API,那么这次的破坏性还要大一点。什么意思?
如果你以前用 Compose 打包了一个 Lib A,并在项目 B 中使用;现在想尝鲜,给 B 升级最新的 Compose,编译虽然可能没问题,但如果 Lib A 实际调用了这次变更的实验性 API,运行时仍可能崩溃。所以要注意了!
我目前发现了,Styles API 中 size 这个函数,就发生了变化。
主要原因是实验性的 Styles API 不承诺二进制兼容性;遇到这类变更时,应一并重新编译并升级相关库。
好,话不多说,马上进入更新解读。
带 key 的 SideEffect 重载
SideEffect 现在支持传入 key。这样一来,特定 key 变化时,可以执行一次性的副作用。如果既不需要协程,也不需要 dispose 回调,它会比 LaunchedEffect 或 DisposableEffect 更合适。
SideEffect 的性能最高可比 LaunchedEffect 快 90%,比 DisposableEffect 快约 20%。
不过,它的执行时机早于 DisposableEffect 与 LaunchedEffect。如果要把现有副作用迁移到这个 API,需要注意这一点,特别是那些依赖于"当前帧完成后才被调度启动"的 LaunchedEffect。
kotlin
@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
SideEffect(key1 = userId, key2 = screenName) {
analytics.logScreenView(userId, screenName)
}
}
作为开发者,我没想到这个功能来的这么迟。
以前如果我们想针对一个 Composable 编写仅在首次进入组合时生效的副作用,只能写 LaunchedEffect(Unit)。不过这个 Effect 需要启动协程,因此会有额外的调度和管理开销。
Mesh Gradients
Compose 1.12 引入了 MeshGradientPainter,用于创建由多个控制点组成、更自然的颜色渐变。

kotlin
val rows = 1
val columns = 1
val gradientPainter = remember {
MeshGradientPainter(rows, columns) {
// 参数:行、列、位置、颜色
setVertex(0, 0, Offset(0f, 0f), Color.Red) // 左上
setVertex(0, 1, Offset(1f, 0f), Color.Blue) // 右上
setVertex(1, 0, Offset(0f, 1f), Color.Green) // 左下
setVertex(1, 1, Offset(1f, 1f), Color.Yellow) // 右下
}
}
Box(
modifier = modifier
.aspectRatio(16 / 9f)
.fillMaxWidth()
.paint(gradientPainter)
)
好酷炫的更新!!!
广色域与 HDR 支持
现在的显示设备可以提供更丰富的色彩和更高的动态范围。Compose 1.12 在 graphics、paint 和 shader 的完整链路中启用了 广色域(P3) 与 HDR 渲染 支持。
非 sRGB 色彩空间定义的颜色,例如 Display P3,现在可以一直保留到平台渲染阶段,不会中途被限制到 sRGB 色域中。如果使用了不支持的色彩空间,例如 CieXyz、CieLab、Oklab;依赖当前 Android 版本不支持的色彩空间,例如 Android 13 及以下的 Bt2020Hlg;或者应用运行在 Android 9(API 28)及以下,颜色会安全回退到 sRGB。
其他值得注意的改动:
GraphicsLayer与Modifier.graphicsLayer新增了LayerOutsets。它可以让图层的视觉边界超出自身测量尺寸。当图层被提升为离屏缓冲区时,可以通过LayerOutsets避免隐式的clipToBounds行为。
Styles
在 Google I/O 上,Google 已经分享过 Compose Styles API 的早期设想:用一套统一且高性能的方式为组件定义样式。
从那之后,Google 一直持续在完善底层架构,希望它具备严格的类型安全与可预测的正确性,同时也能支持自定义设计系统。
这层基础能力还需要继续打磨,因此 API 仍会保持实验性状态,后续也可能出现破坏性变更。
反正现在已经用 AI 编码了,实际上各位可以体验一下。我目前感受最大的变化就是:如果你写了一个复杂的控件,那么使用这个 Styles API 比传递多个 Modifier 好用很多很多!
Modifier 有个特点,就是顺序很重要,这导致了在自定义样式的时候,如果你的控件已经自己用了一部分 Modifier 参数了,那么传入的 Modifier 你很难放在那个位置。同时,如果你想支持多个位置的样式自定义,你就需要传入多个 Modifier,这就会让你的控件看起来很另类------Compose 中的控件多数情况下只有一个 Modifier,而且是第一个参数。
当然,这个 Styles API 的功能实际上和 Modifier 很多功能都是重复的,甚至针对 BasicText 这种控件,样式控制可以通过 Modifier、Styles、TextStyle 控制,Styles 和 TextStyle 都可以用来控制内部文本的样式。希望后续 Google 能够收敛,条条大路通罗马对于开发者并不是一件好事儿。
关于 Styles API 的讲解,大家可以移步这篇文章。
可交互的两阶段过渡
首先,DeferredTargetAnimation 已不再需要 experimental opt-in。
新的 DeferredAnimatedContent 与 DeferredAnimatedVisibility 可以创建两阶段的过渡动画,例如跟随预测返回手势。
手动控制动画: 在过渡的 deferred 阶段,缩放、偏移等动画属性可以实时手动控制,例如直接跟随滑动手势。
平滑接管: deferred 阶段结束后,过渡引擎会接手后续动画,并平滑衔接,其中也包括速度的传递。
共享元素支持: SharedContentConfig 新增 permitTransformDuringDeferredTransition 标志,用于控制共享元素在 deferred 过渡阶段是否随父容器一起进行视觉变换。
kotlin
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)
if (predictiveBackInProgress) {
state.defer(targetScreen)
} else {
state.animateTo(targetScreen)
}
transition.DeferredAnimatedContent(
targetState = targetScreen,
mutableTransformSpec = {
MutableContentTransform {
// 在 deferred 阶段手动控制属性
initialContentTransform { scale = swipeProgress }
}
}
) { screen ->
ScreenContent(screen)
}
下面两个示例展示了这样的场景:手势驱动的动画结束后,再把控制权交给触发式动画。

实际上,这是一个为预测性返回量身定做的动画。
可编辑文本格式
新的 API 为 BasicTextField 的可编辑文本加入了富文本格式能力。现在可以在 TextFieldBuffer 的作用域中,以编程方式应用和修改行内字符格式、段落格式,使用的是 SpanStyle、ParagraphStyle 和新增的 addStyle() 方法。这个作用域可以是 textFieldState.edit { ... },也可以是 InputTransformation。
另外,TextFieldBuffer 提供了 getSpanStyles() 与 getParagraphStyles(),返回的是 TrackedRange 对象,可以读取、更新或移除已经应用的样式。TextFieldState 新增只读属性 textStyles,用于查询不同范围内当前生效的样式;TextFieldBuffer 则提供 originalTextStyles,用于查看编辑前的格式状态。文本格式和自定义 annotation 会在 configuration change 后保留下来。
kotlin
val state = rememberTextFieldState("Formatted text in Compose 1.12")
// 对一段文本应用粗体和颜色
state.edit {
addStyle(
SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
start = 0,
end = 9
)
}
// 从 TextFieldState 查询当前生效的样式
val currentStyles = state.textStyles
文本选择
新的 SelectionState API 可以通过代码控制和观察 SelectionContainer 中的文本选择状态。通过 rememberSelectionState() 创建并提升 SelectionState,再传给 SelectionContainer,就可以拿到响应式的 selectedTexts,它是由 AnnotatedString 组成的列表;同时还可以调用 selectAll()、clear()、select(TextRange)、extendSelectionByWord() 等方法。
另外,可以通过 getSelectableTexts() 按布局顺序获取所有可选择的文本项,并通过全局范围跨多个 SelectionContainer 内的 Composable 选择文本。
kotlin
@Composable
fun ProgrammaticSelectionExample() {
val selectionState = rememberSelectionState()
Column {
Button(
onClick = { selectionState.selectAll() },
modifier = Modifier.disableSelectionClearOnTap()
) {
Text("全选")
}
SelectionContainer(state = selectionState) {
Text("需要通过代码选中的文本内容。")
}
}
}
Credential Manager 集成
Compose 文本输入框现在可以通过 Autofill 框架原生集成 Android 的 Credential Manager(API 34 及以上)。API 34 以下则由 androidx.credential 库处理。给输入框附加新的 credentialRequest 语义属性,并传入 CredentialRequestData 后,就可以在用户输入过程中直接弹出 Passkey、已保存凭据或登录请求。
kotlin
@Composable
fun LoginField(textFieldState: TextFieldState) {
val credentialData = remember {
CredentialRequestData(
// 指定 Credential Manager 的请求选项
)
}
BasicTextField(
state = textFieldState,
modifier = Modifier.semantics {
credentialRequest = credentialData
}
)
}
当然,关于密码的 Autofill,可以看我的这篇文章。
其他值得注意的改动:
- 下载字体支持字体 variation settings;
- 在
SelectionContainer中把选区拖出视口时,现在会自动滚动; - Compose 组件新增自动交互音效支持,包括点击和焦点导航音效;可以使用
SoundEffectOnInteraction关闭。需要注意,这项改动也意味着 semantics 的 click listener 现在必须在主线程调用,少量测试用例可能会受影响; KeyboardType新增Date、Time、DateTime和SignedDecimal;BasicSecureTextField默认使用TextObfuscationMode.System,而RevealLastTyped则是始终显示最后输入字符的强制覆盖选项。
Grid 布局中的命名区域
实验性 Grid 组件现在支持命名区域,复杂的二维布局会更容易维护。
以前需要在每个 item 上维护数字形式的行、列下标;现在可以在 GridConfigurationScope 中定义有实际含义的区域,再通过区域名称放置 Composable。
kotlin
@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
Grid(
config = {
area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
area("sidebar", row = 1, column = 0)
area("content", row = 1, column = 1)
gap(16.dp)
}
) {
HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
MainContentView(modifier = Modifier.gridItem(areaId = "content"))
}
}
之前写过一篇文章讲解 Grid,当时我将 Grid 称之为"响应式布局的最后一块拼图",大家如果想温习一下,可以去看看。
性能
每个版本都会持续投入 Compose 性能,希望框架能够帮助开发者构建好看、同时也足够流畅的应用。
这次主要优化了启动性能。在基准测试中,Compose 的首次显示时间(Time to Initial Display,即应用产出第一帧所需的时间)现在已经可以和 View 相当。

好评!!!我看看以后谁还要说 Compose 启动比 View 慢了
测试同步
Compose 1.12 新增了几个测试 API,用于缩短测试执行时间,并减少状态采样时的不稳定情况:
hasPendingWork:被动检查 UI 是否仍有待处理工作,不会推进时钟。它适合手动驱动动画循环;runWithoutImplicitWait:手动推进时钟帧时,临时关闭隐式同步,例如动画测试。
kotlin
@Test
fun testAnimationStateFast() {
composeTestRule.mainClock.autoAdvance = false
while (composeTestRule.hasPendingWork()) {
composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.waitForIdle()
composeTestRule.runOnUiThread {
composeTestRule.runWithoutImplicitWait {
// 同一帧中查询多个节点时效果最明显。
// 它会避免每次单独查询时重复发生的同步开销。
val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
}
}
}
}
其他值得注意的改动:
captureToImage现在可以把popup或dialog与它的锚点一起截到同一张bitmap中;- 新增
onRootWithViewInteraction,可以将 Compose 语义树的搜索范围限制到指定 AndroidView。对于RecyclerView这类混合 UI,它能简化测试,也不再需要为了测试专门给线上代码加入唯一 tag; @PreviewWrapper注解现在可以用于自定义@MultiPreview类,多个组件就可以复用同一套 Preview 配置,例如自定义主题。
Happy Composing
Compose 1.12 让应用开发有了更多表达空间:Mesh Gradients、广色域支持、可下载的可变字体、Credential Manager 集成,以及更快的测试工具都在这次版本中出现。
来吧,同志们,拥抱 Compose 吧!