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 design interface or code editor only.
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, allowing 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.2.1"
implementation "androidx.compose.ui:ui-tooling-preview:1.2.1"
Composable Preview
A composable is defined by a function, annotated with @Composable
:
@Composable
fun SimpleComposable() {
Text("Hello World")
}
To enable a preview of this composable, you need to create another composable,
annotated with @Composable
and @Preview
, emitting the composable you’ve
created initially:
@Preview
@Composable
fun ComposablePreview() {
SimpleComposable()
}
Finally, click on the split (design/code) view to open the right side panel where your preview will be displayed:
@Preview
accepts parameters to customize the way Android Studio will render
it. You can add these parameters manually in your code, or click on the gutter
icon next to @Preview
to display the configuration picker, to let you select
and change those configuration parameters.
@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 whether the composable is being rendered in a preview.
That lets you do things like showing a placeholder image in the preview window
instead of showing real data. If the composition is being rendered in a preview,
LocalInspectionMode.current
evaluates to true
.
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 in a similar fashion you would do on a device. The interactive mode is isolated in a sandbox environment (isolated from other previews), where you can click elements and enter user input in the preview; the preview even plays animations. It’s a quick way to test different states and gestures of your composable, like a checkbox being checked or empty.
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
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, which means you don't have to write
boilerplate code like 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
will deploy that @Preview to your connected device or emulator.
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 will automatically render all 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")
}
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") } }
}
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.
Copy @Preview
render
Every rendered preview can be copied as an image by right clicking on it.
Set background color
By default, your composable will be displayed with a transparent background.
To add a background, add the showBackground
and backgroundColor
parameters.
Keep in mind that backgroundColor
is a ARGB Long
, not a Color
value:
@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
Text("Hello World")
}
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")
}
}
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))
}
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")
}
@PreviewParameter
You can 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")
)
}
There will be one preview rendered per data element in the sequence:
You can use the same provider class for multiple previews. If necessary, limit the number of previews that will be rendered by setting the limit parameter.
@Preview
@Composable
fun UserProfilePreview(
@PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
UserProfile(user)
}
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.
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
functionprev
to create a@Preview
composable functionpaddp
to add apadding
Modifier in dpweight
to add aweight
ModifierW
,WR
,WC
to surround the current composable with aBox
,Row
, orColumn
container
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:
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:
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:
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
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:
Live Edit
You can accelerate your Compose development experience by using Live Edit in the canary releases of Android Studio Electric Eel. 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.
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:
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:
.
Once you've enabled it, the layout inspector shows recomposition counts on the left, and skipped recompositions on the right:
If you double-click a composable in the layout inspector, you're taken to the corresponding code for analysis.
Animations
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:
You can also use Animation Preview to graph visualize animation curves, which is useful for making sure that the animation values are choreographed properly:
Animation Preview automatically detects inspectable animations, which are
indicated by the Start Animation Inspection icon
.
Animation Preview currently supports the updateTransition
API. To use Animation Preview with updateTransition
, use Compose version
1.0.1 or 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.)