You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中禁用ExoPlayer进度条的向前拖动功能

解决ExoPlayer限制仅能向后拖动/跳转进度条的问题

方案一:拦截Player的所有Seek请求(最彻底)

通过包装ExoPlayer实例,重写seekTo方法统一拦截所有向前跳转的请求,无论触发来源是进度条操作还是代码调用,能覆盖所有场景,完全禁止向前跳转。

代码实现

class ForwardSeekRestrictedPlayer(private val delegate: ExoPlayer) : ExoPlayer by delegate {
    override fun seekTo(positionMs: Long) {
        val currentPlayPosition = delegate.currentPosition
        // 仅允许跳转到当前播放位置或更靠前的位置(向后跳转)
        if (positionMs <= currentPlayPosition) {
            delegate.seekTo(positionMs)
        }
    }

    override fun seekTo(windowIndex: Int, positionMs: Long) {
        val currentPlayPosition = delegate.currentPosition
        if (positionMs <= currentPlayPosition) {
            delegate.seekTo(windowIndex, positionMs)
        }
    }
}

使用方式

将原来的ExoPlayer实例替换为包装后的实例:

val realPlayer = ExoPlayer.Builder(context).build()
val restrictedPlayer = ForwardSeekRestrictedPlayer(realPlayer)
playerView.player = restrictedPlayer

方案二:UI层拦截TimeBar触摸事件(仅限制进度条操作)

如果只需要限制进度条的拖动/点击操作,不影响代码中的seek逻辑,可以直接给DefaultTimeBar设置触摸监听器,在事件传递前拦截向前跳转的操作,响应更及时,解决原方案的延迟问题。

代码实现

val timeBar: DefaultTimeBar? = localPlayerView?.findViewById(R.id.exo_progress) as? DefaultTimeBar
val player = localPlayerView?.player ?: return

timeBar?.setOnTouchListener { v, event ->
    val timeBarView = v as DefaultTimeBar
    val currentPosition = player.currentPosition
    val duration = timeBarView.duration

    if (duration <= 0) return@setOnTouchListener false

    val touchX = event.x
    val totalWidth = timeBarView.width.toFloat()
    // 计算触摸位置对应的目标进度
    val targetPosition = (touchX / totalWidth * duration).toLong()

    when (event.action) {
        MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP -> {
            // 若目标位置大于当前播放位置,拦截触摸事件
            return@setOnTouchListener targetPosition > currentPosition
        }
        else -> return@setOnTouchListener false
    }
}

原方案的问题分析

你之前通过TimeBar.OnScrubListener实现的方案存在以下缺陷:

  • 响应延迟:OnScrubListener的回调在TimeBar默认处理触摸事件之后触发,拦截动作有明显延迟;
  • 位置不准确:onScrubStart获取的是TimeBar处理后的位置,并非用户初始触摸位置,导致判断逻辑失效;
  • 无法拦截点击:用户点击进度条向前跳转时,可能直接触发Player的seek操作,跳过ScrubListener的拦截逻辑。

内容的提问来源于stack exchange,提问作者Ludiras

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:15:37