Jetpack Compose — An Introduction

Hisham Muneer
Android Developers Corner
4 min readMar 18, 2021

--

Compose is the brand new Android UI toolkit written entirely in Kotlin using which you can develop native Android screens and components.

Why we needed a new UI toolkit?

Traditionally we create our views in xmls (a completely different language) and to update the UI’s we mutate them from the Java/Kotlin files by looking up views findViewById() and setting properties on them.

These xml views also hold some state of their own which also needs to be updated when state of the app changes. Keeping App state and view’s state in sync has always been a challenge and it’s developer’s responsibility to ensure they are in sync. In a complex design it becomes more challenging, leading to bugs.

Managing state of App and views in traditional Android app

Mail UI Example…

Let’s assume we are creating the above UI which displays a little differently based on the state of your mailbox.

0 mails → Empty mailbox icon

Less than 99 mails → Mailbox with paper and a Badge

More than 99 mails → A fire icon showing user’s mailbox is on fire

Now based on the number of mails, I might write something like this to handle this UI behaviour.

Now a simple looking UI is not as simple in code as we initially thought. Although the creation logic on the right looks fairly simple. Managing the state of the UI and Mail seems complex as we have to figure out the current state of mailbox and act accordingly.

Compare this with the compose logic below which is straightforward because we don’t have to worry about the current state of the UI, we are going to recreate it when the count changes.

How JetPack Compose do it?

UI components created by compose are relatively stateless, so state issue is majorly gone. Components created by Compose are not exposed as objects instead they are immutable. What this means, you can’t do a tv.setText() or imageView.setVisibility() on a composable view, basically you can’t change a compose view once it is created.

What… How will I update my screen if Compose views are immutable?

We will recreate everything again…

State transformation into UI
Updated State transforms into a new UI

Compose transform State into UI, as UI is immutable and there is no way to update it. If App State changes, we re-execute to transform this new State to new UI.

Recomposition

This reminds of Thanos second plan in Avengers of recreating the whole universe again, maybe it was easy for him with infinity stones but it might be computationally expensive for our Composable runtime to recreate the whole view hierarchy.

Compose does that intelligently by only recreating the views affected by the state change and skipping the views which are unaffected. This process of recreation is called Recomposition.

Let’s Compose

Assuming you have already setup your Compose environment from the following link: https://developer.android.com/jetpack/compose/setup

Let’s write a simple Composable that emits a Text

@Composablefun Greeting(name: String) { 

Text("Hello $name")
}

As you can see our Composable function:

  • is annotated with @Composable
  • can accept data
  • doesn’t return anything, just emits UI

Composable functions should be fast, idempotent, and free of side-effects

Android Studio provides a preview option to see the UI of a composable without running the app. To do that you can mark a composable method with @Preview

@Preview(showSystemUi = true)
@Composable
fun GreetingWithImage() {
Column(modifier = Modifier.padding(16.dp)) {
val typography = MaterialTheme.typography
Image(
painter = painterResource(id = R.drawable.header),
contentDescription = "Image",
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.clip(
shape = RoundedCornerShape(
topStart = 64.dp,
topEnd = 8.dp,
bottomStart = 8.dp,
bottomEnd = 64.dp
)
),
contentScale = ContentScale.Crop
)

Spacer(modifier = Modifier.height(16.dp))
Text("A day in Shark Fin Cove", style = typography.h4)
Text("Davenport, California", style = typography.h5)
Text("December 2018", style = typography.body2)
}
}
Compose @Preview

Things to be aware in Compose

  • Composable functions can execute in any order.
  • Composable functions can execute in parallel.
  • Recomposition skips as many composable functions and lambdas as possible.
  • Recomposition is optimistic and may be canceled.
  • A composable function might run quite frequently, as often as every frame of an animation.

--

--