Guide on Jetpack Compose

Jetpack compose follows Declarative syntaxes for UI — (i.e) code makes the view. It removes the boilerplate of findViewById or ViewBinding references. As on July, 5 2021, it is in beta and good to explore.
Setup
1. Install Android Studio Preview
2. Add the following dependencies.
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling:$compose_version"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.0-alpha06'
implementation 'androidx.activity:activity-compose:1.3.0-alpha02'
3. You might have to add composeOptions in app level build.gradle if there are any build failures like the following.
e: This version (1.0.0-beta08) of the Compose Compiler requires Kotlin version 1.5.10 but you appear to be using Kotlin version 1.4.32 which is not known to be compatible. Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
android {
.....
composeOptions {
kotlinCompilerExtensionVersion compose_version
kotlinCompilerVersion '1.4.30'
}
}
4. Create a new empty ComposeActivity. Or basically extend activity using ComponentActivity()
class MainActivity : ComponentActivity()
5. To set a compose view, we need to use the following —
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
NewComposeMethod()
}
}
}@Composable
fun NewComposeMethod() {
Text("Hello World")
}
Key Elements to start composing —
- @Composable — This annotation specifies the following method is using Jetpack compose for creating views.
- @Preview — Any method annotated with @Preview will be shown onto the studio’s design section. Preview is just for the development, when we run in actual device its not gonna be useful
- setContent{} — Till now we write setContentView(R.layout.some_xml), but for composable function we call method in setContent{}.

Nomenclature —
- Compose methods should start with capital letters
- Good to have granular compose methods, rather than combining many composable objects in one method
- A generic composables (like a view that we include in multiple xmls), should not be coupled inside a class. We don’t want to call that composable method like
classInstance.ComposableMethod()
. - In composables we define spacing using padding there is no margin concept for composables. — https://jetc.dev/slack/2020-07-05-space-by-any-other-name.html.
Just like Flutter has widgets and xml has Views, Jetpack Compose has lot of Composable methods. Like Text, Button, Image, Box, List etc.
Pro tip: Pressing cmd+P or ctrl+P on Android studio, will give all the properties any composable takes.
Starting with Compose
- Text() — This puts a text view on screen. It’s not the edit text.
Text(
text = "Hello World",
color = MaterialTheme.colors.primary,
fontSize = 16.sp,
fontWeight = FontWeight.Medium, // thickness of text
modifier = Modifier.padding(8.dp),
overflow = TextOverflow.Ellipsis
)
In compose the elements such as sp, dp are there as TextUnit and Dp Unit respectively. This is the new way of adding dimensions to any view.
2. Image() —
Image(
painter = painterResource(
R.drawable.luffy
),
contentDescription = null,
modifier = Modifier
.height(56.dp)
.clip(shape = RoundedCornerShape(12.dp)),
)
3. Row() — Just like we have view containers like linear layout with horizontal orientation, in compose we have row for that places its children in a horizontal sequence.
Row(
modifier: Modifier = Modifier,
horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,
verticalAlignment: Alignment.Vertical = Alignment.Top,
content: @Composable RowScope.() -> Unit
)
All the items in the row will be composed at the time of creation. For having a lazy load we have LazyRow which only composes and lays out the currently visible items.
Now, If we want a card with text and image both, I can create another composable like TextImageCard()
@Preview(showBackground = true)
@Composable
fun TextImageCard() {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(horizontal = 8.dp)
) {
Image(
painter = painterResource(
R.drawable.luffy
),
contentDescription = null,
modifier = Modifier
.height(56.dp)
.clip(shape = RoundedCornerShape(12.dp)),
)
Column {
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Title(text = "Luffy")
}
Subtitle(text = "King of the pirates")
}
}
}

Modifier — An ordered, immutable collection of modifier elements that decorate or add behaviour to Compose UI elements. For example, backgrounds, padding and click event listeners etc. All composable elements has modifier implemented.
Modifier
.clickable(onClick = onClick)
.padding(padding)
.fillMaxWidth()
Here the clickable ripple is added with padding.

If we change the order of the functions in modifier, the elements change wrt to it.
Modifier
.padding(padding)
.clickable(onClick = onClick)
.fillMaxWidth()

4. Button() —
Button(onClick = { will execute on click }, contentPadding = PaddingValues(12.dp)) {
Text(text = "Click here")
}
A use case, we want to change the text of the button on the run time by showing how many times it has been clicked
val text = remember {
mutableStateOf("A test button")
}
val count = remember {
mutableStateOf(0)
}
Button(onClick = { text.value = "Clicked ${count.value++}" }, contentPadding = PaddingValues(12.dp)) {
Text(text = text.value,)
}
Why remember?
Before understanding remember we need to understand composition and recomposition.
Composition: A description of the UI built by Jetpack Compose when it executes composables.
Recomposition: Re-running composables to update the Composition when data changes.
Compose is declarative and as such the only way to update it is by calling the same composable with new arguments. These arguments are representations of the UI state. Any time a state is updated a recomposition takes place.
Remember composable is used to store a single object in memory. A value computed by remember
is stored in the Composition during initial composition, and the stored value is returned during recomposition.
remember
stores objects in the Composition, and forgets the object when the composable that called remember
is removed from the Composition. Which also means the state of remember will be lost on activity recreation. So here we should use rememberSaveable.
5. TextField() — Its an edit text. And if we want an Outlined edit text there is another composable called OutlinedTextField. TextField takes value
and onValueChange
as compulsory parameters.
TextField(
value = "The initial value to be shown",
onValueChange = {}
)// For password
val passwordState = remember { mutableStateOf("") }
Box(modifier = Modifier.fillMaxSize().background(color = Color.White))
TextField(
value = passwordState.value,
onValueChange = {
passwordState.value = it
},
placeholder = {},
visualTransformation = PasswordVisualTransformation(),
)
6. Box() — Now what about if we want to add just a view, like its not text view, or a divider. Btw for divider like views there is Divider() composable. Box is like Stack. Every new composable in Box scope will be drawn on top of previous composable.
Box(
modifier = Modifier
.width(52.dp)
.height(26.dp)
.border(
width = 1.dp, color = Color.White, shape = RoundedCornerShape(
topEnd = 10f,
bottomStart = 10f,
)
)
) {
Box(
modifier = Modifier
.background(
color = Color.White, shape = RoundedCornerShape(
topEnd = 10f,
bottomStart = 10f,
)
)
.width(26.dp)
.height(26.dp)
.align(Alignment.TopEnd),
)
}
7. Scaffold() — This is a really easy and way to create a standard app page. It has TopAppBar
, BottomAppBar
, FloatingActionButton
, and Drawer
. By using Scaffold
, it's easy to make sure these components are properly positioned.
Scaffold(
drawerContent = { /*...*/ },
topBar = { /*...*/ },
content = { /*...*/ }
)
Limitations
- It’s little slower than xml to render a change.
Pro tip: I would suggest to create an action shortcut (Cmd + Shift + S) to force render. - Composable animations are in experimental phase. It’s easy to configure animations based on mutable states, and it looks clean. It’s in starting phase, so definitely there will be updates to make it better.
Next article I will create a screen using jetpack compose.