简体   繁体   中英

How to i chain two parts of an animation together in jetpack compose so the the offset increases then decreases?

Ive recently got into doing animations using jet pack compose and am wondering how you can make it so that when you increase a value in an offset, once the animation reaches that value it then changes the value to another value. So like update transition but instead of at the same time, one after the other.

Actually @RaBaKa's answer is partially correct, but it's missing information about how the animation should be run.

It should be done as a side effect. For example, you can use LaunchedEffect : it is already running in a coroutine scope. It is perfectly normal to run one animation after another - as soon as the first suspend function finishes, the second will be started:

val value = remember { Animatable(0f) }
LaunchedEffect(Unit) {
    value.animateTo(
        20f,
        animationSpec = tween(2000),
    )
    value.animateTo(
        10f,
        animationSpec = tween(2000),
    )
}
Text(value.value.toString())

If you want to do this in response to some action, such as pressing a button, you need to run the coroutine yourself. The main thing is to run the animations in the same coroutine so that they are chained.

val value = remember { Animatable(0f) }
val scope = rememberCoroutineScope()
Button(onClick = {
    scope.launch {
        value.animateTo(
            20f,
            animationSpec = tween(2000),
        )
        value.animateTo(
            10f,
            animationSpec = tween(2000),
        )
    }
}) {
    
}
Text(value.value.toString())

The correct answer is to use Kotlin coroutines. I managed to get it working fine. You have to use coroutines in order to launch the animations in the correct sequence like this:

animationRoutine.launch {
    coroutineScope {
        launch {
            animate(
                startingValue,
                targetValue,
                animationSpec = whatYouWant,
                block = { value, _ -> whateverYouNeed = value }
            )
        }
        launch {
            animate(
                initialValue,
                targetValue,
                animationSpec = whatYouWant,
                block = { value, _ -> whateverYouNeed = value }
            )
        }
}

Each of launch scope launches everything in a non blocking way if you tell it to allowing you to run multiple animations at once at a lower level and to sequence the animations you add another coroutine for the next part of the animation.

Maybe you can use Animatable

val value = remember { Animatable(0f) }    //Initial Value

Then in compose you can just use

value.animateTo(20f)

then

value.animateTo(10f) 

For more information visit the official documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM