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

如何实现仅双击触发波纹动画、单击不触发?(ExoPlayer场景)

问题背景

我正在尝试为ExoPlayer实现和YouTube完全一致的视频快进功能,参考相关内容后已成功添加双击监听器。

问题描述

当前遇到的问题:单击视图时也会触发波纹动画,不符合需求——仅希望双击触发快进时显示波纹动画。尝试通过统计点击次数控制波纹可见性,但未达预期,反而出现异常:单击时显示波纹,双击时虽正常触发一次波纹,还会莫名多出现一次(见下方GIF):

波纹异常演示{:width="400"}

GIF画质不佳,敬请谅解

代码示例

  • Kotlin代码
var doubleClickLastTime = 0L
var clicksDone = 0

binding.forward.setOnClickListener {
    if((System.currentTimeMillis() - doubleClickLastTimeF) < 350){
        doubleClickLastTime = 0
        clicksDone = 0
        exoPlayer.seekTo(exoPlayer.contentPosition + 10000)
    }else{
        if (clicksDoneF == 0){
            binding.forward.foreground = null
        }else{
            binding.forward.foreground = with(TypedValue()) {
                this@VideoPlayer.theme.resolveAttribute(
                    android.R.attr.selectableItemBackground, this, true)
                ContextCompat.getDrawable(this@VideoPlayerFromUrl, resourceId)
            }
        }
        clicksDone++
        doubleClickLastTime = System.currentTimeMillis()
    }
}
  • XML代码
<androidx.cardview.widget.CardView
      android:id="@+id/forward"
      android:layout_width="550dp"
      android:layout_height="match_parent"
      app:layout_constraintStart_toEndOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      android:layout_marginVertical="50dp"
      android:foreground="?selectableItemBackgroundBorderless"
      app:cardCornerRadius="16px"
      app:cardElevation="0dp"
      android:backgroundTint="@android:color/transparent"/>
解决方案

核心思路

放弃动态修改foreground控制波纹的方式,改用手动触发波纹动画,仅在确认是双击时执行快进并显示波纹,同时屏蔽默认点击波纹。

具体实现

  1. 修改XML布局
    移除android:foreground属性,避免默认点击触发波纹:
<androidx.cardview.widget.CardView
      android:id="@+id/forward"
      android:layout_width="550dp"
      android:layout_height="match_parent"
      app:layout_constraintStart_toEndOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      android:layout_marginVertical="50dp"
      app:cardCornerRadius="16px"
      app:cardElevation="0dp"
      android:backgroundTint="@android:color/transparent"/>
  1. 用GestureDetector区分单击/双击
    通过手势检测器准确识别双击动作,仅在双击时执行快进并触发波纹:
val gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
    override fun onDoubleTap(e: MotionEvent): Boolean {
        // 执行快进逻辑
        exoPlayer.seekTo(exoPlayer.contentPosition + 10000)
        // 手动触发波纹动画
        val rippleDrawable = ContextCompat.getDrawable(this@VideoPlayer, R.drawable.custom_ripple)
        rippleDrawable?.let {
            it.setBounds(0, 0, binding.forward.width, binding.forward.height)
            binding.forward.foreground = it
            it.start()
            // 动画结束后移除foreground,避免影响后续操作
            it.callback = object : Drawable.Callback {
                override fun invalidateDrawable(who: Drawable) {}
                override fun scheduleDrawable(who: Drawable, what: Runnable, `when`: Long) {}
                override fun unscheduleDrawable(who: Drawable, what: Runnable) {}
                override fun onDrawableStateChanged(who: Drawable) {
                    if (!who.isRunning) {
                        binding.forward.foreground = null
                    }
                }
            }
        }
        return true
    }

    // 屏蔽单击的默认响应
    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
        return true
    }
})

binding.forward.setOnTouchListener { _, event ->
    gestureDetector.onTouchEvent(event)
    true
}
  1. 自定义波纹Drawable(可选)
    若需要和YouTube一致的波纹效果,创建res/drawable/custom_ripple.xml:
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="@color/your_ripple_color"> <!-- 替换为目标波纹颜色 -->
    <item android:id="@android:id/mask">
        <shape android:shape="rectangle">
            <corners android:radius="16dp"/> <!-- 和CardView圆角保持一致 -->
        </shape>
    </item>
</ripple>

原方案问题原因

原方案通过动态修改foreground的时机逻辑有缺陷,单击时的foreground修改会延迟生效,双击时两次点击事件会分别触发foreground的设置与清除,导致出现两次波纹。GestureDetector能准确区分单击和双击,从根源避免该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:20:31