Google is committed to advancing racial equity for Black communities. See how.

Layout preview

You can preview your Jetpack Compose components in Android Studio, without having to deploy your app to a device or emulator. You can have multiple previews of a certain composable function, each with a different width and height restriction, font scaling, or theme. As you develop your app, your previews update to help you review your changes faster.

Create a basic layout preview

To create a layout preview, write a composable function that does not take any parameters, and add the @Preview annotation. After you build your app, the preview function's UI appears in Studio's Preview pane.

For example, suppose you have a composable function that displays a greeting to the user:

@Composable
fun Greeting(name: String) {
    Text (text = "Hello $name!")
}

To preview this function's UI, write a wrapper function that doesn't take parameters, and add the @Preview annotation to the wrapper:

@Preview
@Composable
fun PreviewGreeting() {
    Greeting("Android")
}

Shows a simple "hello world" composable function, a preview function that calls that function, and the preview window displaying the UI emitted by the preview function.

Figure 1. The preview window shows the UI generated by your preview functions.

If you click on a UI element in the preview, Studio takes you to the line where that element is created. For example, if you click on the text "Hello Android!" in this preview window, Studio takes you to the line in Greeting() where the text element is created.

When your code changes, click the refresh button Android Studio compose preview refresh button in the preview window to update the preview. You may need to rebuild your project to update the preview; the preview window tells you if you need to do this.

You can customize the preview by passing parameters to the @Preview annotation. For example, by default the preview's label is based on the name of the preview function, which in this case is PreviewGreeting. You can change the label by passing a name parameter:

@Preview(name = "Android greeting")
@Composable
fun PreviewGreeting() {
    Greeting("Android")
}

For the full list of parameters you can pass to @Preview, see the @Preview reference.

You can define multiple preview functions, which are all shown together in the preview window. For example, you might write functions that test various kinds of input:

@Preview(name = "Long greeting")
@Composable
fun PreviewLongGreeting() {
    Greeting("my valued friend, whom I am incapable of "
    + "greeting without using a great many words")
}

@Preview(name = "Newline greeting")
@Composable
fun PreviewNewlineGreeting() {
    Greeting("world\nwith a line break")
}

Preview window showing several preview functions

Figure 2. If you define multiple preview functions, their UI is all shown in the same preview window.

Deploying previews to your device

To deploy a preview to your default device or emulator, click the deploy button: Android Studio compose preview deploy-to-device button Android Studio creates a new activity containing the UI generated by that function, and deploys it to your app on the device. This lets you try out the UI on an actual device without needing to reinstall the entire app or navigate to its location.

Screenshot of an Android device showing a preview function

Figure 3. The preview of ComposeLongGreeting(), deployed to a virtual device.

Interactive previews

Android Studio provides an interactive preview mode. While you're in interactive preview mode, you can click or type in your UI elements, and the UI responds as if it were in the installed app. To turn interactive preview, click the interactive button over any of your preview windows: Android Studio compose interactive preview button The preview panel switches to interactive mode for that preview function until you exit the mode.

For example, look at this function that responds to user clicks:

@Composable
fun Counter(count: Int, updateCount: (Int) -> Unit) {
    Button(
        onClick = { updateCount(count+1) },
        backgroundColor = if (count > 5) Color.Green else Color.White
    ) {
        Text("I've been clicked ${count} times")
    }
}

@Preview
@Composable
fun PreviewCounter() {
val counterState = state { 0 }

Counter(
            count = counterState.value,
            updateCount = { newCount ->
                counterState.value = newCount
            }
        )
}

The ordinary preview for this function shows you the layout of the UI elements. But if you click on the button, it doesn't respond; instead, Studio takes you to the line where the element was created.

In interactive preview mode, by contrast, when you click the button, the counter increments; when the counter reached 6, the button turns green, just as it would in the running app:

Preview window showing an interactive preview responding to clicks

Figure 4. When the preview window is in interactive mode, it responds to user clicks.

Note: Interactive preview mode does not allow your functions to interact with device storage or network. If you need to test functionality that depends on such operations, you should provide fakes.