Build: Counter Screen
A simple screen that shows a number and a button to increase it. The number remembers its value even if the screen recomposes.
Target UI
------------------- | Counter: 0 | | | | [ Increase ] | -------------------
------------------- | Counter: 0 | | | | [ Increase ] | -------------------
import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.tooling.preview.Preview import androidx.compose.foundation.layout.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable fun CounterScreen() { // TODO: Add state variable here Column( modifier = Modifier.fillMaxSize().padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = "Counter: 0", style = MaterialTheme.typography.headlineMedium) Spacer(modifier = Modifier.height(16.dp)) Button(onClick = { /* TODO: Increase counter */ }) { Text("Increase") } } } @Preview(showBackground = true) @Composable fun CounterScreenPreview() { CounterScreen() }
import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.tooling.preview.Preview import androidx.compose.foundation.layout.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable fun CounterScreen() { var counter by remember { mutableStateOf(0) } Column( modifier = Modifier.fillMaxSize().padding(16.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text(text = "Counter: $counter", style = MaterialTheme.typography.headlineMedium) Spacer(modifier = Modifier.height(16.dp)) Button(onClick = { counter++ }) { Text("Increase") } } } @Preview(showBackground = true) @Composable fun CounterScreenPreview() { CounterScreen() }
We use remember with mutableStateOf to create a state variable counter that survives recompositions of the CounterScreen composable. The by keyword with var counter allows us to read and write the state value directly.
The Text composable shows the current value of counter. When the Button is clicked, we increase counter by 1. Because counter is a state, Compose automatically updates the UI to show the new value.
This pattern is common in Jetpack Compose to keep UI state simple and reactive.
------------------- | Counter: 0 | | | | [ Increase ] | -------------------
remember in Jetpack Compose?rememberremember keeps a value alive during recompositions to avoid resetting.count initialized to 0 using remember and mutableStateOf?remember wraps mutableStateOf to keep state across recompositions.val count = remember { mutableStateOf(0) }. Others misuse function calls or syntax.var count = remember { mutableStateOf(0) }
count.value += 1
println(count.value)What will be printed after this code runs once?count is a mutable state holding 0 initially.count.value += 1 increases value to 1, so printing count.value outputs 1.var count = mutableStateOf(0)
count = remember { mutableStateOf(1) }remember can only be called inside a composable function context.remember called outside composable, which is invalid.remember { mutableStateOf(0) } with var count by delegates state correctly.count++ updates state and triggers UI recomposition.remember, so state resets on recomposition. @Composable
fun Counter() {
var count = 0
Button(onClick = { count++ }) {
Text("Count: $count")
}
}
uses simple var without state, so UI won't update. @Composable
fun Counter() {
val count = remember { 0 }
Button(onClick = { count++ }) {
Text("Count: $count")
}
}
remembers an Int, not mutable state, so increment fails.Pass the test and this pattern moves unknown