一个LottieAnimationView中的动画序列/链接

8

我收到了多个需要使用Lottie库按顺序播放的动画文件

目前我正在尝试重复使用相同的LottieAnimationView,当第一个动画结束时,只需设置下一段动画即可。 代码如下:

private fun playFirstAnimation() {
    binding.animation.setAnimation(R.raw.progress_1)
    binding.animation.repeatCount = 2
    binding.animation.addAnimatorListener(object : Animator.AnimatorListener {
        override fun onAnimationRepeat(animation: Animator?) = Unit
        override fun onAnimationCancel(animation: Animator?) = Unit
        override fun onAnimationStart(animation: Animator?) = Unit

        override fun onAnimationEnd(animation: Animator?) {
            binding.animation.removeAnimatorListener(this)
            notifyFirstAnimationFinished()
            playSecondAnimation()
        }
    })
    binding.animation.playAnimation()
}

private fun playSecondAnimation() {
    binding.animation.setAnimation(R.raw.progress_2)
    binding.animation.repeatCount = 0
    binding.animation.addAnimatorListener(object : Animator.AnimatorListener {
        override fun onAnimationRepeat(animation: Animator?) = Unit
        override fun onAnimationCancel(animation: Animator?) = Unit
        override fun onAnimationStart(animation: Animator?) = Unit

        override fun onAnimationEnd(animation: Animator?) {
            binding.animation.removeAnimatorListener(this)
            notifySecondAnimationFinished()
            playThirdAnimation()
        }
    })
    binding.animation.playAnimation()
}

这里的问题(除了丑陋的代码)是当短时间内更改动画时会出现小闪烁(动画完全消失,其位置上没有任何内容显示)。我不能将所有动画合并成一个,因为我需要知道一个动画何时结束。而且我真的不想为每个动画都有一个单独的LottieAnimationView,并在每次更改时替换它们,因为我可能有很多动画。
在这种情况下,我有哪些选择?
4个回答

9
原来这个问题有一个非常简单的解决方案。我们可以不再调用 setAnimation,而是调用 setComposition 并提供预加载的结果,可以通过 LottieCompositionFactory.fromRawResSyncLottieCompositionFactory.fromRawRes 或其他适合你需求的方法来获取。

你能否提供一个代码示例吗? - Ziad Halabi

0
我将 setAnimation 更改为 setComposition,以便在实际显示它们之前预加载 lottie 文件。
所以不再是:
setAnimation(R.raw.animation)

使用:

LottieCompositionFactory.fromRawResSync(requireContext(), R.raw.animation)?.let { result ->
                                result.value?.let { composition -> setComposition(composition) }
                            }

这对我停止了闪烁。我还为循环使用了AnimationListener。

 private fun setLottieAnimation(lottieView: LottieAnimationView) {
            lottieView.apply {
                var firstAnimation = true
                val loopListener: Animator.AnimatorListener = object : AnimatorListenerAdapter() {
                    override fun onAnimationRepeat(animation: Animator?) {
                        if (firstAnimation) {
                            firstAnimation = false
                            LottieCompositionFactory.fromRawResSync(requireContext(), R.raw.animation_2)?.let { result ->
                                result.value?.let { it -> setComposition(it) }
                            }
                            
                            repeatCount = LottieDrawable.INFINITE
                            playAnimation()
                        }
                    }
                }
    
                LottieCompositionFactory.fromRawResSync(requireContext(), R.raw.animation_1)?.let { result ->
                    result.value?.let { it -> setComposition(it) }
                }
              
                repeatCount = 1
                addAnimatorListener(loopListener)
            }
        }

0
问题在于,动画结束后,您试图将另一个资源加载到相同的“View”中,这是一个繁重的过程,并且与此同时您正在播放动画。一个可行的解决方案是添加延迟。
lottieView.setAnimation("firstlottie.json");
lottieView.playAnimation();
lottieView.addAnimatorListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) {

        }

        @Override
        public void onAnimationEnd(Animator animator) {
            //first animation has ended
            lottieView.pauseAnimation();
            lottieView.setAnimation("secondlottie.json"); //will show only the first frame

            new Handler().postDelayed(new Runnable() {
                 @Override
                 public void run() {
                      lottieView.playAnimation();
                }
             }, 500);
        }

        @Override
        public void onAnimationCancel(Animator animator) {

        }

        @Override
        public void onAnimationRepeat(Animator animator) {

        }
    });

这仍然会产生闪烁。 - SMGhost
@SMGhost 请尝试增加一些延迟,然后更新我。 - Manoj Perumarath
我已经尝试过了,但这并不起作用。每次调用setAnimation都会产生闪烁,然后自动更新可绘制对象。 - SMGhost

0
我已经添加了这段代码,它在我这里运行得很好(递归调用)。
从另一个位置调用。playMyAnimation(1,"file_1.json")
private fun playMyAnimation(count: Int, animFile: String) {
    binding.defaultScreen.animationView.setAnimation(animFile)
    binding.defaultScreen.animationView.speed = 1f

    binding.defaultScreen.animationView.addAnimatorListener(object : Animator.AnimatorListener{
        override fun onAnimationStart(animation: Animator) =Unit

        override fun onAnimationEnd(animation: Animator) {
            binding.defaultScreen.animationView.removeAllAnimatorListeners()
            if(count==1){
                playMyAnimation(2,"file_2.json")
            }else if(count==2){
                playMyAnimation(3,"file_3.json")
            }
        }

        override fun onAnimationCancel(animation: Animator) =Unit

        override fun onAnimationRepeat(animation: Animator) =Unit

    })
    binding.defaultScreen.animationView.playAnimation()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接