I am doing this excersize to build a dice app.
It works but here is what I am confused about: Based on my understanding every time I click on the button Roll it triggers a recompose.
When I click on the Roll button it randomly picks a number between 1 and 6. And then this number is remembered and then the whole screen is recomposed?
And that's when the imageResource is selected based on the result that is remembered from the previous recompose?
And then that is rendered via Image?
Am I understanding this right?
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
var result by remember {mutableStateOf(1)}
val imageResource = when (result) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
Column( modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(imageResource),
contentDescription = result.toString())
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { result = (1..6).random()}) {
Text(stringResource(R.string.roll))
}
}
}
Your overall understanding is correct. However, it might be useful to understand the concept at little but more in depth:
Button
, and a new random value is assigned to the result
variable.result
variable using mutableStateOf()
. This allows Jetpack Compose to detect when you assign a new value to the variable and to trigger the recomposition.result
variable will be recomposed with the new result
value.result
variable will
remember()
will be reset / recomputed.result
variable using remember()
. This ensures that the value of the result variable is not reset during this recomposition.These concepts can be demonstrated in the following example:
@Composable
fun MyComposable() {
var result by remember { mutableStateOf(1) }
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = {
Log.d("MyComposable", "Dices are rolling...")
result = (1..6).random()
}
) {
Text("ROLL")
}
Spacer(modifier = Modifier.weight(1f))
// Composable depends on result variable
// will recompose when result variable is updated
Text(text = "result: $result")
// Composable does not depend on result variable, but has unstable parameter
// will recompose whenever parent Composable recomposes
Text(text = "randomResult: ${(7..12).random()}")
// Composable does not depend on the result variable and has stable parameter
// will not recompose when parent Composable recomposes
Text(text = "some constant text")
// normal Kotlin function
// will be re-executed whenever parent Composable recomposes
Log.d("MyComposable", "Dices are done")
}
}
The Logcat output after each onClick
is as follows:
2024-04-29 10:38:29.122 10618-10618 MyComposable D Dices are rolling...
2024-04-29 10:38:29.137 10618-10618 MyComposable D Dices are done