Android(Kotlin)中如何为Lottie动画不同图层设置不同repeatCount值并动态控制图层可见性
Android(Kotlin)中如何为Lottie动画不同图层设置不同repeatCount值并动态控制图层可见性
我之前在项目里刚好碰到过一模一样的需求,折腾了一阵终于搞定了,给你分享下具体的实现步骤和代码示例:
首先,要给不同图层设置不同的循环次数,因为Lottie默认是给整个动画设置全局的repeatCount,所以得针对单个图层的动画属性来修改。这里的关键是在Composition加载完成后,去调整每个图层的重复参数,或者直接控制对应图层的动画控制器。
1. 为不同图层设置不同的repeatCount
你可以监听Lottie的Composition加载完成事件,然后遍历所有图层,根据图层名称(或者ID)来单独设置repeatCount。不过要注意,Lottie的默认Composition是不可变的,所以我们可以创建一个可变的副本或者直接通过动画控制器来调整:
方法一:通过可变Composition修改图层属性
binding.viewAnimation.addLottieOnCompositionLoadedListener { composition -> // 创建可变Composition副本用于修改图层属性 val mutableComposition = MutableComposition(composition) mutableComposition.layers.forEach { layer -> // 根据图层名称区分处理(名称要和AE导出时完全一致) when (layer.name) { "logo_layer" -> { // 该图层需单次播放 layer.repeatCount = 0 layer.repeatMode = LottieDrawable.RESTART } "background_wave" -> { // 该图层需无限循环 layer.repeatCount = LottieDrawable.INFINITE layer.repeatMode = LottieDrawable.RESTART } } } // 将修改后的Composition设置回View binding.viewAnimation.setComposition(mutableComposition) // 启动动画 binding.viewAnimation.playAnimation() }
方法二:通过动画控制器修改子Animator的循环参数
如果你的Lottie版本不支持MutableComposition,可以通过获取动画的子Animator来单独设置循环参数:
binding.viewAnimation.addLottieOnCompositionLoadedListener { _ -> val mainAnimator = binding.viewAnimation.createAnimator() mainAnimator.childAnimations.forEachIndexed { index, animator -> // 通过索引关联到对应图层,用图层名称做判断 val targetLayerName = binding.viewAnimation.composition.layers[index].name when (targetLayerName) { "logo_layer" -> { (animator as? ValueAnimator)?.repeatCount = 0 } "background_wave" -> { (animator as? ValueAnimator)?.repeatCount = LottieDrawable.INFINITE } } } binding.viewAnimation.setAnimator(mainAnimator) binding.viewAnimation.playAnimation() }
2. 动态控制图层可见性
这个就比较直接了,LottieAnimationView提供了setLayerVisible方法,你只需要传入目标图层的名称(或者ID)和可见性状态就行。比如在你的updateValues函数里可以这么写:
private fun updateValues(modelValue: ModelValue) { isAnimationComplete = false with(binding.viewAnimation) { // 先取消当前动画,清理之前的状态 cancelAnimation() // 根据业务逻辑动态设置图层可见性 setLayerVisible("logo_layer", modelValue.shouldShowLogo) setLayerVisible("background_wave", modelValue.shouldShowWave) // 如果动画未在运行,重新启动动画 if (!isAnimating) { playAnimation() } } }
几个需要注意的小细节
- 图层名称要完全匹配:和AE里导出Lottie时的图层名称、大小写都要对应,否则找不到目标图层
- 状态清理要彻底:动态修改状态前最好先取消当前动画,避免新旧状态冲突
- 单次图层的后续处理:如果需要在单次图层播放完成后做操作,可以添加
addLottieOnAnimationEndListener来监听,比如隐藏图层或者触发业务逻辑
备注:内容来源于stack exchange,提问作者Atul Dhanuka
相关产品推荐
相关产品推荐

