Question about compose and animation. I have a lis...
# compose
m
Question about compose and animation. I have a list of bubble which I want to animate. I have this code: https://gist.github.com/m-maillot/24ab08f338023bf306109d78355790fd A list of bubble will be updated every second by the viewModel. This part works 🙂 The problem comes from the composable
when
in the composable function
Bubble(bubble: Bubble)
which break the padding animation. If I directly use the
fun Bubble(isBig: Boolean)
, the padding animation works. Why a
when
condition will break the animation ? (here my case is simple, it’s a boolean but it can be a sealed class). Edit: put code in a gist.
f
m
Sorry, I move the code in a github gist when I saw the size 😱 , sorry about that.
🙏 2
It’s the same using a if/else condition:
Copy code
@Composable
fun Bubble(bubble: Bubble) {
    if (bubble.isBig) {
        Bubble(isBig = true)
    } else {
        Bubble(isBig = false)
    }
}
Animation doesn’t work... If I don’t use a condition, it works:
Copy code
@Composable
fun Bubble(bubble: Bubble) {
    Bubble(isBig = bubble.isBig)
}
I probably miss something important with compose and animation, but why ? 😞
a
Because
Bubble(isBig = true)
and
Bubble(isBig = false)
are 2 different compositions. Recomposition only works when the parameter of the same composable function invocation changes.
m
Ok, how to deal with a complex object which can render the same object with different Modifier (padding, background...) ? Should I move animations in the parent ?
a
Why not pass the modifier?
f
Wouldn't using
key
help? 🤔
m
@Albert Chang It’s the idea, I setup the animation in the parent which provide the padding through a modifier to the child. I’ll take a look. @Filip Wiesner What is
key
?
a
@Filip Wiesner No. Invocations of
key
at different points won't work.
The value for a key does not need to be globally unique, and needs only be unique amongst the invocations of key at that point in composition.
f
Oh, I see. My bad 😅 I actually never used it so I wasn't sure.
a
I don't know your specific use case so I'm not sure but basically you need to do something like this:
Copy code
@Composable
fun Bubble(bubble: Bubble) {
    Bubble(
        isBig = when (bubble.isBig) {
            true -> true
            false -> false
        }
    )
}
m
Ok, using this code works:
Copy code
@Composable
fun Bubble(bubble: Bubble) {
    val padding by animateDpAsState(
        targetValue = if (bubble.isBig) 50.dp else 10.dp,
        animationSpec = tween(durationMillis = 500, easing = LinearEasing)
    )
    if (bubble.isBig) {
        Bubble(text = "Big bubble", modifier = Modifier.padding(padding))
    } else {
        Bubble(text = "Small bubble", modifier = Modifier.padding(padding))
    }
}
Ok, it works with the animation in the parent. Not very easy to implement.
Indeed, it works @Albert Chang. I see now how it works. The main idea is to keep one
Composable
to help compose to reuse it and keeping animation stuff. Ok, not easy to understand at first place but it’s more clear (I think). Thanks you!
👍 2