Daniele Segato
06/30/2021, 10:46 AMval scale by animateFloatAsState(
targetValue = when {
badgeText.isNullOrBlank() -> 0f
else -> 1f
},
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy
)
)
This makes my badge jump a bit with an animation when a new badge is shown on my icon.
I also want to make it bounce a bit when it changes value (ex. badgeText "1" -> "2"), say bounce to 1.2f scale and than back to 1f.
What's the best way to cause this nudge? I suppose I have to use a LaunchEffect
but than I do not know how to nudge the scale value in an efficient way, thanks in advance for any answerAdam Powell
06/30/2021, 2:23 PMDoris Liu
06/30/2021, 5:44 PMval scale = remember { Animatable(1f) }
LaunchedEffect(key1 = foo) {
scale.animateTo(1.2f, spring(...))
scale.animateTo(1f, spring(...))
}
animateFooAsState
anticipates different target values for different states. That's not really the case here where the (post-animation) target scale is the same for all states. Animatable
is one level below animateFooAsState in the animation system and will therefore give you the control you need (see the diagram here: https://developer.android.com/jetpack/compose/animation#low-level-apis)Daniele Segato
06/30/2021, 8:21 PMDaniele Segato
07/01/2021, 1:25 PMval scaleAnimSpec = remember {
spring<Float>(dampingRatio = Spring.DampingRatioMediumBouncy)
}
val scaleAnimatable = remember {
Animatable(if (badgeText.isNullOrBlank()) 0f else 1f)
}
val scale = scaleAnimatable.value
LaunchedEffect(badgeText) {
val newTarget = if (badgeText.isNullOrBlank()) 0f else 1f
val previousTarget = scaleAnimatable.targetValue
val nudge = !scaleAnimatable.isRunning
&& newTarget == 1f && previousTarget == newTarget
if (nudge) {
scaleAnimatable.animateTo(1.2f, scaleAnimSpec)
}
scaleAnimatable.animateTo(newTarget, scaleAnimSpec)
}
But it kinda surprised me, I though that animateTo
would cancel the previous animation but it looks like it does not?
I was expecting having to do
scaleAnimatable.animateTo(1f, scaleAnimSpec, initialVelocity = 1f)
or something like that to nudge it from 1 and back (actually tried but it had no effect)
May you clarify how is the internal behavior? thank youDoris Liu
07/01/2021, 8:49 PManimateTo
does cancel the previous animation. Your understanding is correct. 🙂 However, in the LaunchedEffect above, the two animateTo calls are a part of the same coroutine. animateTo
doesn't return until the animation has finished. So by calling one animateTo after another, you essentially get a sequential animation.Daniele Segato
07/02/2021, 8:34 AM