0

I have 3 animations, but the top one launches first, then the other two, how do I get them all to launch at the same time? I tried putting them in the same coroutine scope but still getting same results.

LaunchedEffect(isItemInView) {
    scope.launch {
        coroutineScope {
            launch { // Even without the scope.launch, coroutineScope, launch lines, same effect
                bar1.animateTo(if (isItemInView) bar1EndLocation else bar1StartLocation)
                bar2.animateTo(if (isItemInView) bar2EndSize else bar2StartSize)
                bar3.animateTo(if (isItemInView) bar3EndSize else bar3StartSize)
            }
        }

    }
}
Column{
   Bar1(modifier = Modifier.offset(bar1.value.x.dp, bar1.value.y.dp)
   Bar2(modifier = Modifier.size(bar2.value.width.dp, bar2.value.height.dp)
   Bar3(modifier = Modifier.size(bar3.value.width.dp, bar3.value.height.dp)
}

Is there something Im doing wrong here?

Android Dev
  • 305
  • 3
  • 18

2 Answers2

3

As per your code base, you are calling the animateTo function in a coroutine scope. Note that the animateTo function is a suspend function. As a result, the bar2#animateTo won't be executed until bar1#animateTo is executed.

To animate all of them together, you would need to use async-await (Ref: https://stackoverflow.com/a/57458479/5309486 )

launch {
    awaitAll(
        async { bar1.animateTo(if (isItemInView) bar1EndLocation else bar1StartLocation) }
        async { bar2.animateTo(if (isItemInView) bar2EndSize else bar2StartSize) }
        async { bar3.animateTo(if (isItemInView) bar3EndSize else bar3StartSize) }
    )
}

Ashok
  • 2,411
  • 1
  • 13
  • 23
  • 1
    You are my savior, THANK YOU!!!!! I'm new to Android and don't quite have coroutines down so thank you for this!!! It works! – Android Dev Jul 19 '22 at 17:11
2

You can also run animations at the same time by calling launch separately for each Animatable

LaunchedEffect(key1 = isItemInView) {
    launch { bar1.animateTo(if (isItemInView) bar1EndLocation else bar1StartLocation) }
    launch { bar2.animateTo(if (isItemInView) bar2EndSize else bar2StartSize) }
    launch { bar3.animateTo(if (isItemInView) bar3EndSize else bar3StartSize)}
}
Thracian
  • 43,021
  • 16
  • 133
  • 222
  • Wow this works too! Is there any time differences or overhead with using 3 launches vs doing 1 launch with awaitall? Im not really seeing a difference from my end. – Android Dev Jul 19 '22 at 18:25
  • You are calling 3 builder functions, async or launch, in both answers, top launch is not needed. Why you use `async` and `launch` differs. Async is for deferring result while launch is fire and forget. https://stackoverflow.com/questions/46226518/what-is-the-difference-between-launch-join-and-async-await-in-kotlin-coroutines – Thracian Jul 19 '22 at 18:37