Exploring the Latest Jetpack Compose Preview — A Deep Dive into Android’s UI Toolkit
Recently, there have been some exciting new trends in Jetpack Compose development, including the release of Jetpack Compose Preview, a powerful tool that allows developers to see their UI changes in real time as they code. If you have ever built mobile apps using cross-platform frameworks like Flutter or React Native, you will be familiar with this functionality.
In this article, we will explore some of the latest trends in Jetpack Compose development and how the new Jetpack Compose Preview is changing the game for Android app development.
Preparation
First, we need to add the dependency to use compose preview
debugImplementation "androidx.compose.ui:ui-tooling:1.4.0"
implementation "androidx.compose.ui:ui-tooling-preview:1.4.0"
// this will enabled automatically when you initialize your project using compose template
Composable Preview Use Cases
(1) Simple Composable Preview
First, create a new composable function (Uppercase first letter and annotated with Composable).
@Composable
fun SimpleText(
text: String,
) {
Box(modifier = Modifier.background(Color.Cyan).padding(20.dp)) {
Text(
text = text,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.headlineMedium
)
}
}
Then create a new composable function again with a Preview annotation
@Composable
@Preview
fun SimpleTextPreview() {
VentNoteTheme {
Surface {
SimpleText(text = "Example Text")
}
}
}
Then press split to preview the change
The composable preview will look like this :
(2) Multiscreen Preview
We can create multiple screen previews using multiple preview annotations. This feature is useful when developing screens that need to be displayed differently on various device sizes such as phones, tablets, or TVs. To do so, follow the example below :
@Preview(showSystemUi = true, device = "id:Nexus 10")
@Preview(showSystemUi = true, device = "id:6.7in Foldable")
@Preview(showSystemUi = true, device = "spec:width=673.5dp,height=841dp,dpi=480")
@Composable
fun NotesPagePreview() {
NotesPage(
navHostController = rememberNavController(),
viewModel = NotesPageMockVM()
)
}
And the result will be like this (the complete source code is available on the repository at the end of the page ) :
(3) And much more … (find more examples in the official documentation)
There are many more features that you can use in compose preview such as combined multipreview, dimension, background color, theme, locale, etc.
Compose Preview Action Menus
The Android preview layout feature comes with three main actions, there are animation preview, interactive mode, and run preview.
Animation Preview: Using this menu you can inspect animations defined using Jetpack Compose animation framework frame-by-frame. Current API that are supported are updateTransition
, AnimatedVisibility
, and CrossFade
.
Interactive Mode: Using this menu we can make a live preview of gestures like click events (in general you can touch, scroll, or simulate gesture action in this mode) :
Run Preview: Using this menu, we run individually composable in isolation mode on the testing device to see how that particular composable looks on a real device/emulator.
Compose Preview with Injected ViewModel / Contain ViewModel
There will be certain errors when we tend to preview compose a function that has viewModel (especially injected hiltViewModel) that makes previews not possible.
One possible solution, we can create an abstraction from viewModel and make two classes (real & mock ViewModel) that will implement the abstraction. Here is an example :
interface NotesPageBaseVM {
val noteList: LiveData<Result<List<NoteModel>>>
}
@HiltViewModel
class NotesPageVM @Inject constructor(
private val repository: NoteRepository
): ViewModel(), NotesPageBaseVM {
override val noteList: LiveData<Result<List<NoteModel>>> = liveData {
loader.postValue(true)
try {
emitSource(repository.getNoteList()
.onEach {
loader.postValue(false)
}
.asLiveData())
} catch (e: Exception) {
loader.postValue(false)
emit(Result.failure(e))
}
}
}
class NotesPageMockVM: ViewModel(), NotesPageBaseVM {
// or you can initialize with your data
override val noteList: LiveData<Result<List<NoteModel>>> = liveData {}
}
The preview will be passing a mock instance as its parameter like this and the preview will be rendered normally :
@Preview
@Composable
fun NotesPagePreview() {
NotesPage(
navHostController = rememberNavController(),
viewModel = NotesPageMockVM()
)
}
Here is the result we got when we don’t use a mock ViewModel or maybe use a real ViewModel :
So, that was pretty cool, right? This is all the stuff related to Jetpack Compose Preview.
References and Links
Last Words
You can find the complete source code in my repository (please leave a like star button)
Thanks for reading this article. Don’t forget to clap👏/recommend as much as you can and also share 📤 with your friends. It means a lot to me.
Also, Let’s become friends on Linkedin or Instagram. See you in the next article!