How to set a progress listener to compose animatio...
# compose
a
How to set a progress listener to compose animations? I am trying to use
animateFloatAsState
, I see that it accepts a
finishedListener
but how to provide something like an
updateListener
?
m
Do you need a "progress" (something from 0f to 1f) or just want to be notified that something changed? If the latter then you can just rely on the fact that
State<Float>
(returned by
animateFloatAsState
) changes and react on that change.
a
I want to get notified when the animation is half finished. To be more specific, i am rotating an image from 0f to 360f and I want to perform some operation when angle is 180f.
m
Do you want to launch some action (e.g. Effect) or just change some variable based on it (e.g. show different image or color when the angle is 180 or more)?
a
I want to change the image
I have a composable which takes an image (as painter). What I want is that when the argument value changes, my composable should rotate to 180°, update the image and then complete the rotation.
m
then you can just use that float that you have (let's call it
angle
) and do something like:
image = if (angle >= 180f) imageA else imageB
👍 3
👍🏽 1
a
@maciejciemiega I tried implementing what you suggested. One problem i am facing is that my composable takes an image as parameter and remembers it. (The image can change multiple times) When it is recomposed with another value I want to animate the angle and when it reaches 180f, update the remembered image. This way I can just use the remembered image like
Image(painter = rememberedImage)
But how will I know when does angle reaches 180f ? Or am I doing it the wrong way and there exists a simpler solution?
m
still you can base if the angle. For example create another state:
val isFlipped by derivedStateOf { angle >= 180f }
. Then you can add
isFlipped
as a key to the
remember
that you use to cache the image. When
isFlipped
changes the image would be recalculated. It's hard to propose anything specific without seeing the actual code, but I hope you got the idea 🙂
a
Hey @maciejciemiega, This is what I have tried. The problem with this is that it rotates the image first from 0 to 360 and then back from 360 to 0. How can I fix this?
I kind of fixed the reversed rotation issue by modifying the animationSpec as `
Copy code
tween(durationMillis = if (startRotation) 400 else 0)
But I am not sure whether the overall implementation is correct or not (though it seems to work on my device). Like, should the if condition be put in some effect handler or is it fine this way?
m
@Arpit Shukla Can you describe a bit more that exactly you are trying to achieve? Is it something similar to the "crossfade" thing, but rotating one icon into other one with 360 spin? • What should happen if you provide third icon? • Should it spin backward or still 360 in the same direction? • Should it ever spin in a reverse direction or not?
a
@maciejciemiega Yeah, I am changing icons by rotating them. • If third icon comes after previous animation finishes, a new animation should start i.e. 2nd icon should rotate from 0° to 180°, then 3rd icon should replace it and complete the rotation from 180° to 360°. • But if new icon comes while animation was in progress, animation should restart from 0°. • It should never go backward in reverse direction.