I'm trying to mimic the twitter "like count" anima...
# compose
a
I'm trying to mimic the twitter "like count" animation (not the heart, just the count going up). I'm attempting to trigger that animation if the like count is different from the previous like count. So here's some examples code. Let's say I have some class representing likes:
Copy code
data class Like(val count: Int)
And some composable that renders the like count:
Copy code
@Composable
fun LikeText(like: Like) {
    Text("${like.count}"
}
I want to trigger some animation if the like.count value has changed. How would I go about doing that?
k
You can have a
Box
with two
Text
elements. One for the current count, and one for the "next" count. A tap / click triggers an animation that slides up the current count and slides up the next count. Then when the animation is done, you update the current count as well and "move" the texts back to the original places.
Depends on what sort of an animation you're looking for.
a
Yeah that was my game plan with the box/two text elements. What I'm more confused about is how to know when to trigger the animation. Tapping the heart will be one trigger, but others might "like" a post and through a web socket-esque implementation the composable will be updated
d
You could key the animation state on the count, so the animation state resets every time the count changes:
val transitionState = remember(count) { MutableTransitionState(initialState) }
transitionState.targetState = yourTargetState
// Create a transition going from the initial state of the "like" animation to the end
val transition = updateTransition(transitionState)
k
Your count model is the source of truth. Tapping the heart, API call, or whatever - changes the model. And then that change flows into the UI representation on the screen that triggers the animation.
a
@Doris Liu That's kind the direction I started going in (or at least using
remember
to remember previous values of the count). Let me toy around with that, thank you
@Kirill Grouchnikov I understand that the count model is the source of truth, but the part I'm trying to work through is the "trigger the animation" part. In the attached code sample, how would you trigger some animation on that text when the count changes?
k
That's an interesting one. Because the model can change again while you're in the middle of the current animation. So you'd need to also space them apart, so to speak.
If it's a "local" heart tap, it needs to be reflected straight away. But if it's remote data pushes that are happening all the time, those might need to be batched for the UI updates
a
@Doris Liu This is looking super promising - thank you! The only thing I'm struggling with now is how to get the previous like count. Using just
remember
yields the first like count (so if it starts at 1 it looks like it'll always be 1). I know this is outside of the animation realm but what's the process to find out what the previous value of a composable parameter is?
I think I want the
usePrevious
hook in React...
d
What do you need the previous count for?
a
The idea is that the previous count is what would animate up. So if I have 10 likes, as the 10th like comes in "9" would animate up and fade away
d
What happens when there's an 11th like when the "9" is still animating up?
a
Good question, I have no idea. I guess I would expect either the 9 animation to cancel or for another animation to trigger on top of it?
d
That's a question that would affect how you store the previous state(s). 🙂 I would keep a list of all the active states and update it as the animation finishes - whenever count changes, you'd add the new count to the end of the list, when animation finishes, the list is updated to reflect the on-going animations.
a
Oh that's interesting. I'll play around with that, thanks!
d
With the new
AnimatedVisibility
features added in beta07, you could just keep a list of
MutableTransitionState
and prune the list once both
targetState
and
currentState
have become
false
. Unless you build against tip of tree androidx, you might have to wait a bit to use that feature.
This is the new API I was referring to. 🙂
a
Ooo very fancy! I think I'll have to wait for beta07 😛
😀 1
I might be going crazy, but I can't find a hook for when the animation actually finishes. I'm using the transition code you provided earlier
d
You can get the signal from comparing
currentState
against
targetState
, when they are the same, it means the transition has finished.
It may be useful for us to provide a
Flow
of
currentState
change, but I think comparing the two states should give you what you need. 🙂
a
Perfect - that worked like a dream, thank you!
👍 1