使用可组合项预览功能预览您的 UI

可组合项由函数定义,并使用 @Composable 注解进行标注

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

A simple text element containing the words "Hello
World"

要启用此可组合项的预览,请创建另一个同样使用 @Composable@Preview 注解标注的可组合项。这个新的、经过注解的可组合项现在包含了您最初创建的可组合项 SimpleComposable

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

@Preview 注解会告知 Android Studio,应在此文件的设计视图中显示此可组合项。在进行编辑时,您可以实时查看可组合项预览的更新。

A gif showing real time updates using Compose
Preview

您可以在代码中手动添加参数,以自定义 Android Studio 渲染 @Preview 的方式。您甚至可以在同一个函数上多次添加 @Preview 注解,以预览具有不同属性的可组合项。

使用 @Preview 可组合项的主要好处之一是避免依赖 Android Studio 中的模拟器。您可以将内存密集型的模拟器启动过程留给最终的外观和体验调整,而利用 @Preview 轻松进行小的代码更改和测试。

要最有效地利用 @Preview 注解,请务必根据其作为输入接收的状态和作为输出生成的事件来定义您的屏幕。

定义您的 @Preview

Android Studio 提供了一些功能来扩展可组合项预览。您可以更改其容器设计、与其进行交互,或将其直接部署到模拟器或设备上。

尺寸

默认情况下,@Preview 的尺寸会自动选择以包裹其内容。要手动设置尺寸,请添加 heightDpwidthDp 参数。这些值已被解析为 dp,因此您无需在它们后面添加 .dp

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

A yellow square with the words "Hello
World"

动态色彩预览

如果您在应用中启用了动态色彩,请使用 wallpaper 属性切换壁纸,查看您的 UI 如何响应不同用户选择的壁纸。您可以从 Wallpaper 类提供的不同壁纸主题中进行选择。此功能需要 Compose 1.4.0 或更高版本。

在不同设备上使用

在 Android Studio Flamingo 中,您可以编辑 Preview 注解的 device 参数,为不同设备上的可组合项定义配置。

Sample Composable
function

当 device 参数为空字符串(@Preview(device = ""))时,您可以通过按 Ctrl + Space 键来调用自动补全。然后,您可以设置每个参数的值。

Editing the sample
function

通过自动补全,您可以从列表中选择任何设备选项(例如 @Preview(device = "id:pixel_4"))。或者,您可以通过选择 spec:width=px,height=px,dpi=int… 来输入自定义设备,从而设置每个参数的单独值。

Spec
list

要应用,请按 Enter 键;要取消,请按 Esc 键。

如果您设置了无效值,该声明下方会出现红色下划线,并且可能会提供修复建议(Alt + Enter(macOS 为 ⌥ + ⏎)> Replace with …)。检查功能会尝试提供最接近您输入内容的修复方案。

Example of invalid
value

语言区域 (Locale)

要测试不同的用户区域设置,请添加 locale 参数

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

A simple text element containing the word "Bonjour" with a French
flag

设置背景颜色

默认情况下,您的可组合项显示为透明背景。要添加背景,请添加 showBackgroundbackgroundColor 参数。请记住,backgroundColor 是 ARGB Long 类型,而不是 Color 值。

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

A green rectangle with the words "Hello
World"

系统 UI

如果您需要在预览中显示状态栏和操作栏,请添加 showSystemUi 参数。

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

A preview window showing an activity with the status and action bars.

UI 模式

uiMode 参数可以接受任何 Configuration.UI_* 常量,并允许您相应地更改预览的行为。例如,您可以将预览设置为“夜间模式”,以查看主题如何反应。

Compose preview UI

LocalInspectionMode

您可以从 LocalInspectionMode CompositionLocal 中读取,以查看可组合项是否在预览中渲染(在可检查组件内)。如果组合项是在预览中渲染的,则 LocalInspectionMode.current 的求值结果为 true。此信息允许您自定义预览;例如,您可以在预览窗口中显示占位符图像,而不是显示真实数据。

通过这种方式,您还可以绕过限制。例如,显示示例数据而不是调用网络请求。

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

与您的 @Preview 进行交互

Android Studio 提供了允许您与定义的预览进行交互的功能。这种交互有助于您了解预览的运行时行为,并使您能够更好地通过预览浏览 UI。

交互模式

交互模式允许您像在运行程序的设备(如手机或平板电脑)上一样与预览进行交互。交互模式在沙盒环境中隔离(即与其它预览隔离),您可以在其中点击元素并在预览中输入用户数据。这是测试可组合项的不同状态、手势甚至动画的快速方法。

The user clicking the preview's "interactive"
button

A video of the user interacting with a
preview

代码导航和可组合项大纲

您可以将鼠标悬停在预览上,查看其中包含的可组合项的大纲。点击可组合项大纲会触发编辑器视图跳转到其定义位置。

The user hovering over a preview, causing Studio to display the outlines of
its
composables

运行预览

您可以在模拟器或物理设备上运行特定的 @Preview。该预览会作为新的 Activity 部署在同一个项目应用中,因此它共享相同的上下文和权限。如果权限已被授予,您无需编写任何申请权限的样板代码。

点击 @Preview 注解旁边或预览顶部的“运行预览”图标 运行预览图标,Android Studio 就会将该 @Preview 部署到您连接的设备或模拟器上。

The user clicking the preview's "run preview"
button

Video of the user deploying a preview to the
device

复制 @Preview 渲染图

通过右键点击每个已渲染的预览,可以将其作为图像进行复制。

The user clicking on a preview to copy it as an
image.

同一个 @Preview 注解的多个预览

您可以展示同一个 @Preview 可组合项的多个版本,这些版本具有不同的规范,或者传递给可组合项的不同参数。通过这种方式,您可以减少本来需要编写的样板代码。

多预览模板

androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01+ 引入了多预览 (Multipreview) API 模板:@PreviewScreenSizes@PreviewFontScales@PreviewLightDark@PreviewDynamicColors,因此通过一个注解,您就可以在常见场景下预览 Compose UI。

Previewing different fonts and screen sizes using templates

创建自定义多预览注解

借助多预览功能,您可以定义一个注解类,该类本身具有多个具有不同配置的 @Preview 注解。将此注解添加到可组合函数会自动一次性渲染所有不同的预览。例如,您可以使用此注解同时预览多个设备、字体大小或主题,而无需为每个可组合项重复这些定义。

首先,创建您自己的自定义注解类

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

您可以将此自定义注解用于您的预览可组合项

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

Android Studio design tab showing the composable with small and large font

您可以组合多个多预览注解和普通预览注解,以创建更完整的预览集。组合多预览注解并不意味着会显示所有不同的组合。相反,每个多预览注解都是独立运行的,并且仅渲染其自己的变体。

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

Android Studio design tab showing the composable in all configurations

多预览(以及普通预览!)的混合搭配特性,让您能够更全面地测试大型项目中更多的属性。

@Preview 和大型数据集

通常,您需要将大型数据集传递给可组合项预览。为此,只需通过添加带有 @PreviewParameter 注解的参数,将示例数据传递给可组合项预览函数即可。

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

要提供示例数据,请创建一个实现 PreviewParameterProvider 的类,并以序列的形式返回示例数据。

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

这会针对序列中的每个数据元素渲染一个预览

Previews showing Elise, Frank and Julia
composables

您可以将同一个提供程序类用于多个预览。如果需要,可以通过设置 limit 参数来限制预览的数量。

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

使用 @PreviewParameter 的预览默认使用参数索引和属性名称(user 0, user 1, user 2 等)进行命名,这可能难以区分它们。为了提高预览清晰度,您可以通过在 PreviewParameterProvider 中重写 getDisplayName() 来为每个预览提供自定义显示名称。这有助于区分不同的数据变体或 UI 状态。例如,您可以根据输入数据标记预览。

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

Previews with custom display names showing Elise - 30, Frank - 31 and Julia - 40
composables

AI 辅助预览生成

Android Studio 中的 AI 代理可以自动为您的可组合项生成 Compose 预览。右键点击一个可组合函数并选择 AI > Generate Preview for [Composable name]。代理会分析您的可组合项以生成带有正确参数的必要 @Preview 样板代码,帮助您快速验证 UI 是否按预期渲染。

使用 AI 生成 Compose 预览。

注解类 @Preview

您随时可以在 Android Studio 中按住 'ctrl 或 ⌘ + 点击' @Preview 注解,查看自定义预览时可调整的完整参数列表。

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

限制和最佳实践

Android Studio 直接在预览区域执行预览代码。它不需要运行模拟器或物理设备,因为它利用了 Android 框架的一个移植部分,称为 LayoutlibLayoutlib 是一个专为在 Android 设备之外运行而设计的 Android 框架自定义版本。该库的目标是在 Android Studio 中提供非常接近设备上渲染效果的布局预览。

预览限制

由于预览在 Android Studio 中的渲染方式,它们非常轻量,不需要完整的 Android 框架即可渲染。然而,这带来以下限制:

  • 无网络访问
  • 无文件访问
  • 某些 Context API 可能无法完全使用

预览和 ViewModels

在可组合项中使用 ViewModel 时,预览受到限制。预览系统无法构造传递给 ViewModel 的所有参数,例如存储库、用例、管理器等。此外,如果您的 ViewModel 参与依赖注入(例如使用 Hilt),预览系统也无法构建完整的依赖图来构造 ViewModel

当您尝试预览使用 ViewModel 的可组合项时,Android Studio 在渲染该特定可组合项时会显示错误。

Android studio problem pane with Failed to instantiate a `ViewModel`
message

如果您想预览使用 ViewModel 的可组合项,您应该创建另一个可组合项,将来自 ViewModel 的参数作为可组合项的参数传递。这样,您就不需要预览使用 ViewModel 的可组合项了。

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

其他资源

  • 如需详细了解 Android Studio 如何提高 @Preview 的易用性,并获取更多工具提示,请查看博客 Compose Tooling
  • 有关旧版视图指南,请参阅使用视图开发布局