I have this class, and for the most part I just do...
# compose
z
I have this class, and for the most part I just do
Checkable(x) { .. }
and that works great. When I instead have
if(x) Checkable(true) { .. } else Checkable(false) { .. }
then the Switch composable differs between the two and jumps between the states instead of animating. I think I know why - the context in which the switch is rendered differs, both checked & the lambda differs - but how can I fix that?
Copy code
data class Checkable(
    val checked: Boolean,
    val enabled: Boolean = true,
    val onCheckedChanged: (Boolean) -> Unit,
) : SettingsAction {
    override val onClick = {
        onCheckedChanged(!checked)
    }

    @Composable
    override fun RowScope.Render() {
        Switch(
            checked = checked,
            enabled = enabled,
            onCheckedChanged = onCheckedChanged,
        )
    }
}
My only wish is to keep the SettingsAction & Checkable classes as they are.
d
Not sure why you would put a
render
or a
onClick
in a
data class
, that are suppose to contain data, but anyway: > When I instead have
if(x) Checkable(true) { .. } else Checkable(false) { .. }
then the Switch composable differs between the two and jumps between the states instead of animating. You are switching between two composables instead of using the same one. You can simplify the logic by simply writing
Checkable(x)
z
Correct me if Im wrong, but - the checkable class is not a composable, so I dont think that Im switching between two?
d
I'm not sure how you are invoking render here, but my bet is that Compose simply does not understand that you are referencing the same Composable. In the structure you have no arguments going in to the composable function it is all just part of the data class.
z
No wait, sorry - I just realized that theres actually nothing wrong here. What is wrong is that I was wrapping one of the checkables in another action, which explains why the switch is not identical between the two branches 🤦🏽‍♂️
Yep, that was it! Works perfectly now. Also makes it very clear to me that doing x.let { Y(it) } is easy to miss.
d
Why not just
Y(x)
? 🙃 let doesn't add anything in that case.
z
Copy code
Checkable(false) {
    scope.launch {
        loading = true

        requester.authorize()?.let { account ->
            emitter emit AuthorizedSync(account)
        }

        loading = false
    }
}.let { Loadable(loading, it) } <--