Jetpack Compose makes it easy to build beautiful UI. Check out this Chat UI sample, and learn some exciting bits of Compose along the way!
•6 months ago
Simple color management
Starting simple, we'll take a look at the color management of the sample. Since it doesn't support dark mode, and doesn't need a large palette, it doesn't make use of the color systems provided by
MaterialTheme. Instead, it groups all colors used in a simple
These are really straightforward to use, for example, here's the implementation of the small green circles that are used as online indicators:
To attempt to match the font in the sample, we used the free Metropolis font. Adding a custom font in a Compose app is simple: add the resources, create a font family, and then apply it in the theme.
Add the resources to the
Here, we've added five different variants of the Metropolis font. Be careful to use names that the Android resource system can handle (avoid spaces and capital letters).
FontFamily and configure it in the theme.
These resources can be wrapped in
Font objects, specifying the weight and style that each font file corresponds to. Then, they can all be added to a
FontFamily like so:
This font family is part of the
Typography options in the theme:
Which will be contained by the app theme, like so:
Set font weights as needed.
CleanChatTheme applied at the root of the Compose tree, the font family will automatically be applied to
Text elements in the app.
To get a specific variant of the font, such as bold, specify the weight when creating a
The @ReadOnlyComposable annotation
Sometimes you need access to the composable environment in a function, but won't emit any UI inside it. In these cases,
@ReadOnlyComposable can be used to tell the compiler about this to perform certain optimizations.
Take the following function: it transforms a
User into a
String that describes their last active status (currently online or seen X time ago). To do this, it uses the
stringResource composable function.
As you'd expect, composables marked with
@ReadOnlyComposable can only call other composables that are also marked with
@ReadOnlyComposable. For example, trying to create a
Text inside this function would result in an error.
Of course, this means that the
stringResource function being used above is also marked as a
The @Preview annotation
@Preview is a core part of Jetpack Compose tooling, and it can be used to preview small composable snippets, such as:
Notably, the annotation comes with a large array of parameters that you can use to customize the previews.
For example, the previews don't show a background by default, so whatever your IDE's theme is will serve as the background, which often makes for a bad experience if the composable you're previewing doesn't create its own background.
showBackground = true parameter to the annotation means the difference between these two looks:
There are many options available on this annotation to set the size and locale, show the system UI, create groups of previews, and so on. For a deeper exploration of the available options, check out this article by Joe Birch.
Getting spacing around lists right has been a difficult task with the old View system. Should you add padding or margins? How will content get cut off, where and how will the overscroll animation be displayed?
Another frequent task is adding space between the list elements, for this you'd implement your own
RecyclerView.ItemDecoration class, where you'd then write pixel values into an
outRect based on various parameters.
Compose makes this all a lot easier. There are two main parameters you can use to configure spacing on a
As opposed to regular padding (using
Modifier.padding) which would add padding outside the composable and cut off the contents of the list, content padding is added inside the composable, meaning that content will be able to scroll into this padded area.
Here's the same
LazyRow with regular padding and content padding, when scrolled to the left:
PaddingValues objects has various different constructor functions: you can specify the same padding on all sides, horizontal and vertical padding separately, or individual values for all sides!
horizontalArrangement parameters (on
LazyRow, respectively) can be used to easily add spacing between the elements of the list, by using
This makes the following change to the list:
Local Composable functions
Kotlin offers local functions to create short, simple functions that will only be used within another function (and shouldn't even be exposed to others within the same file, like
private functions would be).
This works with
@Composable functions as well - credit goes to Gabor Varadi for this idea. Here's an example of creating a very small, simple composable to be used inside another:
That's a wrap for now! Hope you discovered some useful new features of Jetpack Compose along the way. Remember, you can find the full source code of the sample on GitHub, if you wanna play around with the code yourself.
Curious about Compose? Check out our previous article where you can learn how to build a real, functional Android Chat app with Jetpack Compose.
To add a real messaging feature to your app, check out Stream's Chat SDK for Android. It's easy to get started with the in-app messaging tutorial, and you can find more details on the GitHub page of the Android SDK.