你写过多少个重复的 @Preview?Compose 终于要解决这个问题了

打开你的项目,搜一下 MyTheme {

在 Preview 函数里找到了多少个?

10 个?50 个?更多?

每加一个 @Preview,就得手动套一层主题。不套也能跑,但用的是 Material 默认主题------你自定义的颜色、字体、圆角全都不对,看到的不是真机效果。这个烦恼折磨 Compose 开发者三年,Google 终于在这周把修复合并进了 AndroidX 主线。

PreviewWrapper 来了。

问题是什么

Compose 的 @Preview 有个根本性的缺陷:它不知道你的 App 主题。

所以每个 Preview 函数里,你都得自己把内容包进 MyAppTheme {} 里:

kotlin 复制代码
@Preview
@Composable
fun ButtonPreview() {
    MyAppTheme {          // ← 每次都要写
        Surface {         // ← 每次都要写
            MyButton("点我")
        }
    }
}

@Preview
@Composable
fun CardPreview() {
    MyAppTheme {          // ← 又写一遍
        Surface {         // ← 又写一遍
            MyCard()
        }
    }
}

一个组件还好,几十个组件全是这个模式。

更烦的场景是:设计系统升级了,主题初始化方式变了。你要改的不是一处,是全项目所有 Preview 函数。

PreviewWrapper 怎么用

这次合并进 AndroidX 的变更(CL #3950845,已于 2026-03-03 merge 到 androidx-main)引入了两个新 API:

  • PreviewWrapper 接口
  • @PreviewWrapperProvider 注解

用法分三步:

第一步:定义一个 Wrapper

kotlin 复制代码
object MyAppPreviewWrapper : PreviewWrapper {
    @Composable
    override fun WrapContent(content: @Composable () -> Unit) {
        MyAppTheme {
            Surface(color = MaterialTheme.colorScheme.background) {
                content()
            }
        }
    }
}

就是一个实现了 PreviewWrapper 接口的 object,WrapContent 里写你想套的壳。

第二步:创建你自己的 Preview 注解

kotlin 复制代码
@PreviewWrapperProvider(MyAppPreviewWrapper::class)
@Preview
annotation class MyAppPreview

@PreviewWrapperProvider 指向你的 Wrapper,再加上 @Preview,就变成了你的自定义 Preview 注解。

第三步:到处用,再也不重复

kotlin 复制代码
@MyAppPreview
@Composable
fun ButtonPreview() {
    MyButton("点我")   // ← 主题自动套上了
}

@MyAppPreview
@Composable
fun CardPreview() {
    MyCard()           // ← 同样,干净
}

就这样。打开 Android Studio 的 Preview 面板,主题、Surface、背景色,全都在。

和多 Preview 注解配合

很多团队已经在用多 Preview 注解(同时预览多个设备/字号/暗色模式):

kotlin 复制代码
@Preview(name = "Light", uiMode = UI_MODE_NIGHT_NO)
@Preview(name = "Dark", uiMode = UI_MODE_NIGHT_YES)
@Preview(name = "Large Font", fontScale = 1.5f)
annotation class MultiPreview

PreviewWrapper 可以直接和这个组合:

kotlin 复制代码
@PreviewWrapperProvider(MyAppPreviewWrapper::class)
@Preview(name = "Light", uiMode = UI_MODE_NIGHT_NO)
@Preview(name = "Dark", uiMode = UI_MODE_NIGHT_YES)
@Preview(name = "Large Font", fontScale = 1.5f)
annotation class ThemedMultiPreview

一个注解,三种状态,全部带主题。

能做什么,不能做什么

适合用 PreviewWrapper 的场景:

  • 统一注入 App 主题(最常见)
  • 统一加 Surface / 背景色
  • 注入 CompositionLocal(如 LocalDensity、LocalContext mock)
  • 给整个团队统一 Preview 规范

不适合的场景:

  • 运行时逻辑 ------ Wrapper 只在 Android Studio Preview 渲染时生效,发布的 APK 里不存在
  • 替代 @PreviewParameter ------ 后者是提供数据,Wrapper 是提供容器,两者正交,可以同时用

什么时候能用

目前这个 CL 刚合并进 androidx-main(2026-03-03),还没有发布到稳定版。

跟进路径:

  • ui-tooling-preview 的 alpha 版本发布
  • 或者直接用 AndroidX snapshot 版本提前体验

API 已经定型(通过了 API Review +2 和 Code Review),稳定版应该不会有大改动。

为什么这件事值得关注

这不只是少写几行代码的便利改动。

大团队的 Compose 代码库里,Preview 函数往往有几百个。主题不统一、有人忘了套壳、设计更新要全局修改------这些都是真实的管理成本。

PreviewWrapper 把"每个 Preview 函数的规范"变成了"统一定义一次的注解"。这才是重要的地方。


你们项目里有多少个重复的 Preview 包装?到时候能删掉多少行代码?欢迎评论区晒一下。

#JetpackCompose #AndroidDev #Kotlin #Android开发

相关推荐
用户860225046747218 小时前
从入门到进阶的 React Native 实战指南
android·前端
沐言人生18 小时前
ReactNative 源码分析10——Native View创建流程createView
android·react native
问心无愧051318 小时前
ctf show web入门98
android·前端·笔记
李斯维19 小时前
Jetpack 生命周期组件 Lifecycle 的设计思想和使用
android·android studio·android jetpack
Mr YiRan19 小时前
Android构建优化:基于Git Diff+TaskGraph
android·git·elasticsearch
赏金术士19 小时前
第二章:Compose入门—声明式UI编程
android·ui·kotlin·compose
星间都市山脉19 小时前
Android 谷歌 VTS 完整测试
android
齊家治國平天下19 小时前
Android 14 AIDL HAL 使用指南-获取服务流程解析
android·hal·aidl·servicemanager·aidl hal·获取服务
张二娃同学19 小时前
02_C语言数据类型_整型浮点型字符型一次讲清楚
android·java·c语言
lf28248143119 小时前
07 AD9361自发自收PL工程搭建
android