Published February 27, 2020
(Updated 3/20/2020 with vector drawing changed from dev07 release)
Jetpack Compose is a new library from the Android team that simplifies UI creation. Small, composable functions create the building blocks of your view. Combining these building blocks form higher-level views and your full UI.
This blog series focuses on Jetpack Compose by recreating some well known views from popular applications. My first copy-cat attempt is a Tweet view. This example provides room to explore composable functions and manage state.
The view for a single tweet is small but it holds a lot of data.
For a composable app, separate functions represent each of these components. These functions should be small. Their only responsibility providing a component to display their arguments.
Once these individual components are in place, they are combined together to create the full view. Each post in this series will look at a different part of the Tweet view. This first post focuses on setting up a project with Compose and displaying the user’s display name, Twitter handle, and Tweet time.
The first step to use Compose is downloading the right version of Android Studio. Version 4.1 of Android Studio is required but at this time only the canary version includes Compose. The 4.0 beta version does not work with compose at this time so make sure to use canary. Find canary versions at the Android Studio archive page.
The only difference when creating a new project is the starter activity. The ‘Empty Compose Activity’ provides the basic template for a composable activity.
The min SDK version must be at least 21 before creating the project. Once the project is ready, building the app populates the preview pane. If the preview pane is not open, clicking on the split button in the top-right of the screen opens it on the right.
At the time of this writing, the version of the Jetpack Compose library provided in the template project is behind the latest version. I did not run into issues with this until trying to deal with vector image loading but updating it now ensures I am using the current APIs.
I update the versions of four compose dependencies to dev07 from dev02.
The compiler requires some additional compose options in the android block. These options specify the Kotlin compiler version and extension versions so everything works with compose.
With these in place I have the right version of compose as well as the right kotlin compiler extensions. For details on the current version of compose, check out the compose release notes.
Finally, deleting the bulk of the default code in
MainActivity helps simplify things.
The first composable functions are for the user information at the top of the tweet. These are the user’s display name, Twitter handle, and Tweet time. Displaying text in compose involves creating a composable function whose only responsibility is to display the text. Since there are three text items, I add three functions for each item.
Note that these functions are not defined inside of the
class. They should be usable from other classes as well. I just put them in the
same file for convenience.
Each function has the
@Compose annotation so the system knows these are
composable functions. Each function has a
String parameter for the text to
With these low-level functions in place, I combine them into a higher-level function representing the row of text.
To display items in a row with compose, you use the
Row component. This
component accepts a lambda argument with each of the items it needs to
Building composable functions is quick and I want to be able to verify they look
correct before continuing. Adding the views to my
MainActivity view is one
option but then I have to wait for the project to build and deploy each time I
want to change something. A better alternative is the
Applying this annotation to a composable function renders its content in
the preview pane in Android Studio. I use this to create a preview function to
view the progress of my tweet view. For now, it displays my current
MaterialTheme allows me to apply a theme to my composable functions but I
am not using it right now. In a later blog post I will take a look at
what the theme does and how to modify it.
While the row displays all of the text, it still looks pretty bad.
All of the text is the same size and there is no space between any of the
items. By default, the
Row takes up as much space as all of the child
items and leaves no extra space for padding.
Fortunately, adding space to the text is straightforward. I started by looking
DisplayName composable. There is a
modifier parameter to
Text composable where padding can be applied.
LayoutPadding object has two constructors. The one I use above specifies
the padding for the left, top, right, and bottom of the view separately.
I only pass in a value for the right padding so I can add space
DisplayName and the
Handle. The other constructor accepts a
single parameter and applies that value to all four areas around the view.
With that padding in place, I copy this padding to the
Handle composable to
add space between the twitter handle and post time.
Last up for this post is styling the text to look more like the Tweet view. The
DisplayName should be bold with a black color to draw attention while the
PostTime should be a regular font style and a gray color. All of the text should also be
smaller. I’ll start with the
To modify the style of
Text there is a
style parameter that accepts
TextStyle object. The options on this class allow full control of how the
text is displayed.
DisplayText I need three of the attributes. I pass in a color,
font size, and font weight. This implementation makes clear that the
Android team put a lot of effort into making a clear API that is easy to
TextStyle applied to the
PostTime functions makes the
text look right.
Once the text styles are in place and the preview refreshes, things look much better.
To complete the style, modifying the row with its own padding ensures the text has space between it and the other tweet content.
In this post I setup a project using Jetpack Compose and displayed some text, as well as styled the text and added padding. The next few blog posts will focus on displaying images, handling click events, and dealing with state in Compose. Stay tuned for more!