You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动