https://kotlinlang.org logo
#compose-android
Title
# compose-android
k

KotlinLeaner

11/16/2023, 12:49 PM
Hi guys, I have simple compose function for counter logic. On counter logic I want to change float value. I tried some piece of code using
derivedStateOf
but it not working. Instead if I used simple condition logic it working fine.
Copy code
@Preview(showBackground = true)
@Composable
fun Experiment() {
    Surface {
        var count by remember { mutableStateOf(0) }
        ExperimentView(count) {
            count++
        }
    }
}

@Composable
fun ExperimentView(count: Int, onCountChange: () -> Unit) {
    Column {
        val floatValue by remember {
            derivedStateOf {
                if (count % 2 == 0) {
                    0.4F
                } else {
                    0.2F
                }
            }
        }
        Text(text = "$count with float value $floatValue")
        Spacer(modifier = Modifier.height(20.dp))
        Button(onClick = { onCountChange() }) {
            Text(text = "Button")
        }
    }
}
Float value is never changing with the use of
derivedStateOf
. If I removed
derivedStateOf
it working fine. I am adding working example in below
Copy code
@Composable
fun ExperimentView(count: Int, onCountChange: () -> Unit) {
    Column {
        val floatValue =
            if (count % 2 == 0) {
                0.4F
            } else {
                0.2F
            }

        Text(text = "$count with float value $floatValue")
        Spacer(modifier = Modifier.height(20.dp))
        Button(onClick = { onCountChange() }) {
            Text(text = "Button")
        }
    }
}
So why this is happening in this code? Thanks
s

Stylianos Gakis

11/16/2023, 12:51 PM
derivedStateOf can only be notified for changes for
MutableState
, not just any value. In your case, your “count” variable is
count: Int
not
count: MutableState<Int>
.
k

KotlinLeaner

11/16/2023, 12:52 PM
So what is the solution for this ?
For your very specific case, you can do something as simple as
Copy code
@Composable
fun ExperimentView(count: Int, onCountChange: () -> Unit) {
    val countState by rememberUpdatedState(count)
    Column {
        val floatValue by remember {
            derivedStateOf {
                if (countState % 2 == 0) {
                    0.4F
                } else {
                    0.2F
                }
            }
        }

        Text(text = "$count with float value $floatValue")
        Spacer(modifier = Modifier.height(20.dp))
        Button(onClick = { onCountChange() }) {
            Text(text = "Button")
        }
    }
}
And that should work already, as now you’d be reading from a
MutableState
inside your
derivedStateOf
z

Zach Klippenstein (he/him) [MOD]

11/16/2023, 8:51 PM
Even if
count
were a snapshot state object, it wouldn’t make sense to use
derivedStateOf
here because the calculation is very simple, and the overhead of
derivedStateOf
would not be worth it.
1
k

KotlinLeaner

11/20/2023, 8:27 AM
Thank you got it...