Android Studio support for Compose

Stay organized with collections Save and categorize content based on your preferences.

Android Studio brings a lot of new features specifically for Jetpack Compose. It embraces a code-first approach while improving the developer productivity without having to choose between using design interface or code editor.

A fundamental difference between View-based UI and Jetpack Compose is that Compose doesn’t rely on View to render its composables. As a consequence of this architecture approach, Android Studio offers extended features for Jetpack Compose without having to open an emulator or connect to a device. Compared to Android Views, this allows a faster, iterative process for developers to implement their UI designs.

To enable Android Studio-specific features for Jetpack Compose, you need to add these dependencies in your application build.gradle file:

debugImplementation "androidx.compose.ui:ui-tooling:1.3.2"
implementation "androidx.compose.ui:ui-tooling-preview:1.3.2"

Composable Preview

A composable is defined by a function, and annotated with @Composable:

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

A simple text element containing the words

To enable a preview of this composable, create another composable, annotated with @Composable and @Preview. This new, annotated, composable now contains the composable you created initially, SimpleComposable:

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

The @Preview annotation tells Android Studio that this composable should be shown in the design view of this file. Starting with Android Studio Electric Eel, you can see live updates to your composable preview as you make your edits.

A gif showing real time updates using Compose Preview

You can add parameters manually in your code to customize the way Android Studio renders @Preview. You can even add the @Preview annotation to the same function multiple times to preview a composable with different properties.

@Preview features

Android Studio offers some features to extend composable previews. You can change their container design, interact with them, or deploy them directly to an emulator or device.

LocalInspectionMode

You can read from the LocalInspectionMode CompositionLocal to see if the composable is rendered in a preview (inside an inspectable component). If the composition is rendered in a preview, LocalInspectionMode.currentevaluates to true. This information allows you to do customize your preview; for example, you can show a placeholder image in the preview window instead of showing real data.

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

Interactive mode

The interactive mode allows you to interact with a preview similarly to how you would on a device running your program, like a phone or tablet. The interactive mode is isolated in a sandbox environment (meaning, isolated from other previews), where you can click elements and enter user input in the preview. It’s a quick way to test different states, gestures, and even animations of your composable.

Preview interactive mode runs directly inside Android Studio without an emulator running, which results in some limitations:

  • No network access
  • No file access
  • Some Context APIs may not be fully available

The user clicking the preview's

A video of the user interacting with a preview

Deploy Preview

You can deploy a specific @Preview to an emulator or physical device. The preview is deployed within the same project app as a new activity, so it shares the same context and permissions. It does not require you to write boilerplate code asking for a permission if it has already been granted!

Click the Deploy to Device icon next to the @Preview annotation or at the top of the preview, and Android Studio deploys that @Preview to your connected device or emulator.

The user clicking the preview's

Video of the user deploying a preview to the device

Use with different devices

In Android Studio Electric Eel, you can edit the device parameter of the Preview annotation to define configurations for your Composables in different devices.

Sample Composable function

When the device parameter has an empty string (@Preview(device = “”)), you can invoke autocomplete by pressing Ctrl + Space. Then, you can set the values of each parameter.

Editing the sample function

From autocomplete, you can select any device option from the list–for example, @Preview(device = “id:pixel_4”). Alternatively, you can enter a custom device by choosing spec:width=px,height=px,dpi=int… to set the individual values of each parameter.

Spec list

To apply, press Enter, or cancel with Esc.

If you set an invalid value, the declaration is underlined in red and a fix may be available (Alt + Enter (⌥ + ⏎ for macOS) > Replace with …. The Inspection attempts to provide a fix that is closest to resembling your input.

Example of invalid value

Multipreview Annotations

With multipreview, you can define an annotation class that itself has multiple @Preview annotations with different configurations. Adding this annotation to a composable function automatically renders all of the different previews at once. For example, you can use this annotation to preview multiple devices, font sizes, or themes at the same time without repeating those definitions for every single composable.

Start by creating your own custom annotation class:

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

You can use this custom annotation for your preview composables:

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

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

You can combine multiple multipreview annotations and normal preview annotations, to create a more complete set of previews. Combining multipreview annotations doesn't mean all the different combinations are shown. Instead, each multipreview annotation acts independently and renders only its own variants.

@Preview(
    name = "dark theme",
    group = "themes",
    uiMode = UI_MODE_NIGHT_YES
)
@FontScalePreviews
@DevicePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview() {
    MyTheme { Surface { Text("Hello world") } }
}

Android Studio design tab showing the composable in all configurations

The mix-and-match nature of multipreview-- and normal preview!-- lets you more comprehensively test many properties of larger scale projects.

Code navigation and composable outlines

You can hover over a preview to see the outlines of the composables contained within. Clicking on a composable outline triggers your editor view to navigate to its definition.

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

Copy @Preview render

Every rendered preview can be copied as an image by right clicking on it.

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

Set background color

By default, your composable is displayed with a transparent background. To add a background, add the showBackground and backgroundColor parameters. Keep in mind that backgroundColor is an ARGB Long, not a Color value:

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

A green rectangle with the words

Dimensions

By default, @Preview dimensions are chosen automatically to wrap its content. If you want to set the dimensions manually, you can add heightDp and widthDp parameters. Keep in mind those values are already interpreted as dp-- you don't need to add .dp at the end of the value:

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

A yellow square with the words

Locale

To test different user locales, you need to add the locale parameter:

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

A simple text element containing the word

System UI

If you need to display the status and action bars inside a preview, add the showSystemUi parameter:

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}
A preview window showing an activity with the status and action bars.

UI mode

The parameter uiMode can take any of the Configuration.UI_* constants and allows you to change the behavior of the preview accordingly. For example, you can set the preview to Night Mode to see how the theme reacts.

Compose preview UI

@Preview tips

Benefits and best practices

One of the primary benefits of using @Preview composables is to avoid reliance on the emulator in Android Studio. You can save the memory-heavy startup of the emulator for more final look-and-feel changes, and @Preview's ability to make and test small code changes with ease.

To leverage @Preview annotation most effectively, make sure to define your screen(s) in terms of the state it receives as input and the events that it outputs. In addition to improved testability, your screen(s) render easily in your preview!

@Preview and large data sets

Very often, a need arises where you must pass a large data set to your composable preview. To do this, simply pass sample data to a Composable Preview function by adding a parameter with the @PreviewParameter annotation.

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

To provide the sample data, create a class that implements PreviewParameterProvider and returns the sample data as a sequence.

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

This renders one preview per data element in the sequence:

You can use the same provider class for multiple previews. If necessary, limit the number of previews by setting the limit parameter.

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

annotation class Preview

You can always 'command + Click' on the @Preview annotation in Android Studio for a full list of parameters that can be adjusted when customizing your 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
)

Additional Resources

To read more about how Android Studio promotes @Preview ease of use, and more Tooling tips, check out the blog Compose Tooling.

Editor actions

Android Studio has also features inside the editor area to improve your productivity with Jetpack Compose.

Live Templates

Android Studio has added these Compose-related live templates, which allow you to enter code snippets for fast insertion by typing the corresponding template abbreviation:

  • comp to set up a @Composable function
  • prev to create a @Preview composable function
  • paddp to add a padding Modifier in dp
  • weight to add a weight Modifier
  • W, WR, WC to surround the current composable with a Box, Row, or Columncontainer

Gutter icons

Gutter icons are contextual actions visible on the sidebar, next to the line numbers. Android Studio introduces several gutter icons specific to Jetpack Compose to ease your developer experience.

Deploy preview

You can deploy a @Preview to the emulator or physical device directly from the gutter icon:

The user clicking a preview function's deploy gutter icon, and deploying the preview to the device

Color picker

Whenever a color is defined inside or outside a composable, its preview is shown on the gutter. You can change the color via the color picker by clicking on it like this:

The user clicking a color in the gutter, bringing up a color picker

Image resource picker

Whenever a drawable, vector, or image is defined inside or outside a composable, its preview is shown on the gutter. You can change it via the image resource picker by clicking on it like this:

The user clicking an icon in the gutter, bringing up the resource picker

Iterative code development

As a mobile developer, you’re often developing your app’s UI step by step rather than developing everything at once. Android Studio embraces this approach with Jetpack Compose by providing tools that don’t require a full build to inspect, modify values and verify the final result.

Live edit of literals

Android Studio can update in real time some constant literals used in composables within previews, emulator, and physical device. Here are some supported types:

  • Int
  • String
  • Color
  • Dp
  • Boolean

Video of the user changing literals in the source code, and the preview updating dynamically

You can view constant literals that trigger real time updates without the compilation step by enabling literal decorations through the Live Edit of literals UI indicator:

Enabling Live Editing of Literals

Live Edit

You can accelerate your Compose development experience by using Live Edit in the canary releases of Android Studio Flamingo. Live Edit is a more powerful version of Live edit of literals. The functionality allows you to see the effect of updates to composables in real time by automatically deploying code changes to an emulator or device.

Overview of Live Edit UI

Apply Changes

Apply Changes allows you to update code and resources without having to redeploy your app to an emulator or physical device (with some limitations).

Whenever you add, modify, or delete composables, you can update your app without having to redeploy it by clicking on this button:

User clicking the

Layout Inspector

Layout inspector allows you to inspect a Compose layout inside a running app in an emulator or physical device.

Get recomposition counts

You can use the layout inspector to check how often a composable is recomposed or skipped. If your UI has poor performance, this is often because of a coding error that forces your UI to be recomposed excessively. On the other hand, some coding errors can prevent your UI from being recomposed when it needs to be, which means UI changes aren't showing up on the screen. Tracking recompositions can help find both of these kinds of problems.

To track recomposition, turn on Show Recomposition Counts in the view options:

Recomposition counts enabled in view options.

Once you've enabled it, the layout inspector shows recomposition counts on the left, and skipped recompositions on the right:

Recomposition counts shown in layout inspector

If you double-click a composable in the layout inspector, you're taken to the corresponding code for analysis.

Animation Preview

Android Studio allows you to inspect animations from Animation Preview. If an animation is described in a composable preview, you can inspect the exact value of each animated value at a given time, pause the animation, loop it, fast-forward it, or slow it, to help you debug the animation throughout its transitions:

Play back, scrub through, and slow down the AnimatedVisibility

You can also use Animation Preview to graph visualize animation curves, which is useful for making sure that the animation values are choreographed properly:

Visualization of an animation curve

Animation Preview automatically detects inspectable animations, which are indicated by the Start Animation Preview icon Run icon.

Start Animation Preview icon in Design window

If you have multiple animations, you can use Animation Preview to inspect and coordinate them all at once. You can also freeze a specific animation.

Gif showing inspection with All Animations UI

Animation Preview currently supports the updateTransition and AnimatedVisibility APIs. To access the latest features, use Animation Preview with Android Studio Electric Eel and Compose 1.2.0-alpha01 and higher.

Enable experimental features

Some features are only available after enabling them manually in the experimental section within Android Studio preferences: File > Settings > Experimental (Android Studio > Preferences > Experimental on a Mac.)

Compose tooling enabled inside the Android Studio Experimental preferences