How to use animation listener for Lottie animation in Android Jetpack Compose?
Asked Answered
G

3

12

In Android View System, We can use animation listener like below to get lottie animation callbacks.

 playView = LottieAnimationView(this)
 playView.addAnimatorListener(object : Animator.AnimatorListener {
        override fun onAnimationStart(animation: Animator?) {
        }

        override fun onAnimationEnd(animation: Animator?) {
           
        }

        override fun onAnimationCancel(animation: Animator?) {
        }

        override fun onAnimationRepeat(animation: Animator?) {
        }
    })

How we can add listener using Jetpack Compose? i added below code currently to play the lottie animation. I want to receive the callback after animation play completed.

@Composable
fun PlayView() {
    val animationSpec = remember { LottieAnimationSpec.RawRes(R.raw.play_anim) }
    val result: LottieCompositionResult by remember { mutableStateOf(LottieCompositionResult.Loading) }
    val context = LocalContext.current
    LottieAnimation(
        animationSpec,
        modifier = Modifier
            .fillMaxHeight()
            .fillMaxWidth()
    )

    if (result is LottieCompositionResult.Success) {
        //start the next flow
    }
}
Grindstone answered 25/6, 2021 at 20:14 Comment(0)
B
27

Updated answer to version 1.0.0-rc01-1 of Lottie.

What you can do is:

val composition by rememberLottieComposition(
    LottieCompositionSpec.RawRes(R.raw.your_lottie_file)
)
val progress by animateLottieCompositionAsState(composition)

LottieAnimation(
    composition,
    modifier = Modifier
        .size(200.dp)
        .background(Color.Black),
) 

if (progress == 1.0f) {
    // Animation completes.
}
Buxton answered 26/6, 2021 at 15:15 Comment(4)
Looks like in latest version, above code will not work. they have removed animationState parameter in LottiAnimation()Grindstone
But as per the documentation, below callbacks available but did not see any sample code. airbnb.io/lottie/#/android-compose "Access error, isLoading, isComplete, isFailure, and isSuccess properties."Grindstone
i guess they didnt implement some thing like lottieProgressAsStateJimerson
ths, the code work in latest version right now. "progress" is a state, compose really will do it after animation finished.Doehne
U
2

I was able to achieve this using the LottieAnimationState returned by animateLottieCompositionAsState(). In this case, I play the animation 3 times, then hide it, but you could put anything in the block where isAnimationVisible is set to false.

Note that I was using lottie-compose v6.4.0 here.

var isAnimationVisible by remember { mutableStateOf(true) }

if (isAnimationVisible) {
    val composition by rememberLottieComposition(LottieCompositionSpec.Asset("animation.json"))
    val animationState = animateLottieCompositionAsState(
        composition = composition,
        iterations = 3
    )

    LaunchedEffect(animationState.progress) {
        if (animationState.progress == 1f) {
            // Animation finished
            isAnimationVisible = false
        }
    }

    composition?.also {
        LottieAnimation(
            composition = it,
            progress = { animationState.progress },
        )
    }
}
Urinary answered 21/6 at 22:39 Comment(0)
N
0

You can use animatable isAtEnd/isPlaying/progress for that (6.4.0v)

    val composition by rememberLottieComposition(
        LottieCompositionSpec.RawRes(R.raw.your_lottie_file)
    )
    var shouldPlayAnimation by remember { mutableStateOf(false) }
    val animatable = rememberLottieAnimatable()

    LaunchedEffect(composition, shouldPlayAnimation) {
        if (composition == null || !shouldPlayAnimation) return@LaunchedEffect
        animatable.animate(composition, iteration = 1)
    }

    LottieAnimation(
        composition = composition,
        progress = { animatable.progress },
        modifier = Modifier
            .size(300.dp, 200.dp)
    )

    LaunchedEffect(animatable.isAtEnd) {
        if (animatable.isAtEnd) {
            shouldPlayAnimation = false
            animatable.resetToBeginning()
        }
News answered 10/6 at 8:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.