You are on page 1of 40

Introduction to

Jetpack Compose
Responsive and user-friendly UI designs for Android apps
M Taufiq Hidayat
Android Developer @ XL Axiata
Mentor @Makkode Academy
Contents

Things we’ll talk about

● What is Compose? ● Modifer


● Compose Lifecycle ● State in compose (core)
● Layout and Alignment ● Lazy Layout
● Migration Strategy (Bonus)
What is Jetpack Compose?
The idea behind the framework

Jetpack Compose is a new and fully declarative way to design and render
Android user interfaces.

It relies on composable functions, modifiers and reacting to state changes to


display beautiful, material-design-inspired UI using Kotlin!
Benefits of using Jetpack Compose

Accelerates
Less code Intuitive Powerful
Development

Compatible with all your existing Create beautiful apps with direct
Do more with less code and Just describe your UI, and
code so you can adopt when access to the Android platform
avoid entire classes of bugs. Compose takes care of the rest.
and where you want. Iterate fast APIs and built-in support for
Code is simpler and easier to As app state changes, your UI
with live previews and full Material Design, Dark theme,
maintain automatically updates.
Android Studio support. animations, and more
Compose Lifecycle
Layout & Alignment
Column Row Box Constraint Layout
1. Column 2. Row 3. Box
Modifier
Modifiers allow you to
decorate or augment a
composable
List of Compose modifiers | Jetpack Compose | Android Developers
State and Event
Any Value that can
change over time
Creating a State
@Composable
fun CartItem() {
var quantity: Int = 1

Row {
Button(onClick = { quantity++ }) {
Text("+")
}
Text(quantity.toString())
Button(onClick = { quantity-- }) {
Text("-")
}
}
}
State not tracked by Compose
@Composable This state is
fun CartItem() { not tracked
var quantity: Int = 1 by Compose

Row {
Button(onClick = { quantity++ }) {
Text("+")
}
Text(quantity.toString())
Button(onClick = { quantity-- }) {
Text("-")
}
}
}
State changes need to
be tracked by
Compose
Compose State APIs

interface State<out T> {


I val value: T
● State<T> }

interface MutableState<T> : State<T> {


I override var value: T
● MutableState<T> ...
}
State tracked by Compose
@Composable
fun CartItem() {
val quantity: MutableState<Int> = mutableStateOf(1)

Row {
Button(onClick = { quantity.value++ }) {
Text("+")
}
Text(quantity.value.toString())
Button(onClick = { quantity.value-- }) {
Text("-")
}
}
}
State created in
composables needs to
be remembered
Three way to create state
State tracked and remembered by Compose
@Composable
fun CartItem() {
val quantity = remember { mutableStateOf(1) }

Row {
Button(onClick = { quantity.value++ }) {
Text("+")
}
Text(quantity.value.toString())
Button(onClick = { quantity.value-- }) {
Text("-")
}
}
}
Use Property delegate
@Composable
fun CartItem() {
var quantity by remember { mutableStateOf(1) }

Row {
Button(onClick = { quantity++ }) {
Text("+")
}
Text(quantity.toString())
Button(onClick = { quantity-- }) {
Text("-")
}
}
}
State tracked and remembered by Compose
@Composable
fun CartItem() {
val quantity = remember { mutableStateOf(1) }

Row {
Button(onClick = { quantity.value++ }) {
Text("+")
}
Text(quantity.value.toString())
Button(onClick = { quantity.value-- }) {
Text("-")
}
}
}
BONUS — rememberSaveable
@Composable
fun CartItem() {
val quantity = rememberSaveable { mutableStateOf(1) }

Row {
State survives
Button(onClick = { quantity.value++ }) {
Text("+") configuration
} changes
Text(quantity.value.toString())
Button(onClick = { quantity.value-- }) {
Text("-")
}
}
}
UI update loop
Lazy Layout
How about List? 1 2

1. LazyColumn
produces a vertical scrolling list
of an unknown length

2. LazyRow
produces a horizontal scrolling
list of an unknown length
Say goodbye to
Recylerview and
Adapter
Migration strategy in
Existing App
Use ComposeView
1. app/build.gradle

buildFeatures {
...
compose true
}

dependencies {

val composeBom = platform("androidx.compose:compose-bom:2022.10.00")


implementation composeBom

implementation("androidx.compose.material:material")
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")

}
2. Use compose view

3. Set into fragment or activity


Use AbstractComposeView
Bridge between androidView and Jetpack
compose, decouple all the needed Jetpack
Compose code into a Class
THANK YOU

You might also like