Lottie Android技术问询:区间播放重复及播放暂停按钮状态控制
Hey,我来帮你搞定这两个Lottie Android的实际开发问题,都是我之前做项目碰到过的场景,直接上干货:
问题1:指定区间播放+重复循环
Lottie Android原生就支持控制播放区间和重复逻辑,分两种常用方式,你按需选:
方式一:按帧控制(推荐,精准度高)
Lottie动画的帧是固定的,用帧控制最稳妥,步骤如下:
- 先拿到你的
LottieAnimationView实例 - 等动画的
Composition加载完成(本地资源也可以同步获取,但异步监听更稳妥) - 设置起止帧、重复模式和次数,最后启动播放
代码示例(Kotlin):
val lottieView = findViewById<LottieAnimationView>(R.id.your_lottie_view) lottieView.setAnimation("your_anim.json") // 本地资源或远程URL // 监听动画资源加载完成 lottieView.addCompositionListener { composition -> // 假设你想播放20-80帧,无限重复 lottieView.setMinAndMaxFrame(20, 80) // 重复模式:RESTART(每次从区间起点播)/ REVERSE(来回播) lottieView.repeatMode = LottieDrawable.RESTART // 重复次数:-1=无限,正数=重复N次 lottieView.repeatCount = LottieDrawable.INFINITE lottieView.playAnimation() }
方式二:按进度控制(0.0~1.0对应动画首尾)
如果你的动画是按进度划分区间的(比如想播中间20%到80%的内容),用这个:
lottieView.addCompositionListener { composition -> lottieView.setMinAndMaxProgress(0.2f, 0.8f) lottieView.repeatMode = LottieDrawable.RESTART lottieView.repeatCount = LottieDrawable.INFINITE lottieView.playAnimation() }
⚠️ 中途切换区间的话,记得先调用cancelAnimation()再重新设置参数哦。
问题2:音频联动的播放/暂停Lottie按钮
这个核心是根据音频状态切换Lottie的播放状态和区间,我假设你的Lottie动画是设计师常用的帧结构:
- 0~10帧:播放按钮的静态/过渡状态(显示播放图标)
- 11~50帧:暂停图标+一次完整的均衡器动画
- 之后重复11~50帧实现均衡器循环
你可以根据自己的动画实际帧数值调整,直接看代码逻辑:
第一步:监听音频播放器状态
以MediaPlayer为例,先把播放/暂停的状态监听搭好:
val mediaPlayer = MediaPlayer().apply { // 这里初始化你的音频数据源、准备逻辑 setOnPreparedListener { updateLottieState(isPlaying = true) } setOnCompletionListener { updateLottieState(isPlaying = false) } } // 把Lottie本身当按钮用,点击切换音频状态 val lottieBtn = findViewById<LottieAnimationView>(R.id.lottie_play_pause_btn) lottieBtn.setOnClickListener { if (mediaPlayer.isPlaying) { mediaPlayer.pause() updateLottieState(isPlaying = false) } else { mediaPlayer.start() updateLottieState(isPlaying = true) } }
第二步:实现Lottie状态切换核心逻辑
private fun updateLottieState(isPlaying: Boolean) { val lottieBtn = findViewById<LottieAnimationView>(R.id.lottie_play_pause_btn) if (isPlaying) { // 音频播放中:先播放到暂停图标状态,再循环均衡器 lottieBtn.cancelAnimation() // 先播0~10帧,切换到暂停图标 lottieBtn.setMinAndMaxFrame(0, 10) lottieBtn.repeatCount = 0 // 只播一次 lottieBtn.playAnimation() // 监听这次播放结束,开启均衡器循环 lottieBtn.addAnimatorListener(object : Animator.AnimatorListener { override fun onAnimationStart(anim: Animator?) {} override fun onAnimationEnd(anim: Animator?) { // 切换到均衡器循环区间(11~50帧) lottieBtn.setMinAndMaxFrame(11, 50) lottieBtn.repeatCount = LottieDrawable.INFINITE lottieBtn.repeatMode = LottieDrawable.RESTART lottieBtn.playAnimation() // 记得移除监听,避免重复触发 lottieBtn.removeAnimatorListener(this) } override fun onAnimationCancel(anim: Animator?) {} override fun onAnimationRepeat(anim: Animator?) {} }) } else { // 音频暂停:直接停在播放图标帧(这里用第0帧) lottieBtn.cancelAnimation() lottieBtn.frame = 0 lottieBtn.setMinAndMaxFrame(0, 0) // 固定在播放帧 lottieBtn.repeatCount = 0 } }
补充小提示
如果你的Lottie是把播放/暂停做成了不同图层,也可以用lottieBtn.setMinAndMaxLayer()控制显示哪个图层,但帧序列的方式更通用,不用依赖图层命名。
内容的提问来源于stack exchange,提问作者leegor




