https://kotlinlang.org logo
b

Boris Kachscovsky

06/23/2021, 5:23 PM
We’re trying to implement an indeterminate progress spinners whose animations are synchronized between screens. Is this possible in compose? Would it be possible to base it off some shared value (e.g. time)?
d

Doris Liu

06/23/2021, 5:52 PM
Do you have a mock for what that might look like?
b

Boris Kachscovsky

06/23/2021, 6:05 PM
Currently it works like this
Copy code
val rotation = remember { Animatable(initialValue = 0f) }

    LaunchedEffect(Unit) {
        rotation.animateTo(
            targetValue = 359f,
            animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
        )
    }
But it would be great if it could accept some offset
Copy code
val rotation = remember { Animatable(initialValue = 0f, offset = System.currentTimeMillis() % 359) }

    LaunchedEffect(Unit) {
        rotation.animateTo(
            targetValue = 359f,
            animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
        )
    }
If the offsets were synced like this, the animations would sync too! I can’t give it as the initial value because we still want it to animate from 0 - 359, so an offset would be ideal
d

Doris Liu

06/23/2021, 6:09 PM
offset
is for the delay I assume? Consider sequencing the delay and animation in the LaunchedEffect:
Copy code
val rotation = remember { Animatable(initialValue = 0f) }
    LaunchedEffect(Unit) {
        delay(offset)
        rotation.animateTo(
            targetValue = 359f,
            animationSpec = infiniteRepeatable(IndeterminateProgressAnimationSpec)
        )
    }
b

Boris Kachscovsky

06/23/2021, 6:16 PM
Ah that makes sense 👍 But the idea is that the infinite repeatable animation wouldn’t delay, just have the animation offset by a certain amount of time. So if animation 1 shows on the screen it’ll start at let’s say 50. After 500 milliseconds the animation would be at (50 + 500) % 359 = 191. The second animation should then start at 191 given that they’re using the same underlying composable and the offset would be based on the current time. I wonder if there’s a way to do something similar with this API
d

Doris Liu

06/23/2021, 6:28 PM
ah, so the offset is offsetting the animation in the opposite direction than delay. 🙂
The second animation should then start at 191 given that they’re using the same underlying composable and the offset would be based on the current time.
What triggers the 2nd animation to start? It sounds like the stateless animation API (e.g. TargetBasedAnimation) would be best suited for this case. With TargetBasedAnimation, you can drive it with any arbitrary rule that might apply on playtime.
🙌 1
b

Boris Kachscovsky

06/23/2021, 6:30 PM
What triggers the 2nd animation to start?
It’s the loading spinner on the following screen, but i’ll take a look at
TargetBasedAnimation
! Thanks for the help 🙏
d

Doris Liu

06/23/2021, 6:35 PM
Maybe the spinner animation could be hoisted to the common parent, if you are going for a continuous animation when switching the screen. Each screen would be receiving the necessary animated values for drawing the spinner. That's another way to go about this. 🙂
🛗 2
2 Views