Viewpager2切换视频播放,要求禁止某个视频禁止上划或者下滑

1 以下的场景都是,使用viewpager2实现了抖音视频切换播放的场景逻辑
需求是 要求观看到某一集视频要求该视频必须完整看完,才能切换到下一集视频。
此刻 我们必须将viewpager2切换到当前的fragment进行上滑拦截,或者上滑拦截

2 大家通常的用法是重写viewpager2,但是 viewpager2 是final类型,禁止重写。我们只能另寻方案

3 可能大家会觉得比较简单,但是你测试的时候会发现,如果上划一下段距离,在下拉 必然可以拉倒下一个item,拦截事件只有在当前的item在屏幕底部的时候有效,有时候就无法拦截,这个很烦躁。

4 解决方法是 它本身是用了recycleview,你可以把他当成这个。也就是说 我们需要监听每一个recycleview的item的 touch事件,进行实践拦截。

5 上代码
1
override fun onStart() {
super.onStart()
setScroll()
}

private fun setScroll() {
    // Initialize the NoSwipeItemTouchListener with default settings
    noSwipeListener = NoSwipeItemTouchListener(
        currentpostion,
        requireContext(),
        disableUpScroll = false,
        disableDownScroll = false
    )
    touchInterceptor = ViewPagerTouchInterceptor(getViewPager())

// touchInterceptor.addTouchInterceptorToViewPager(noSwipeListener)
// 上划和下滑都可以滑动
setVerticalScroll(true, true)

}

// 设置是否可以上划或者下滑 false 不可以滑动 true 可以滑动
fun setVerticalScroll(up: Boolean, down: Boolean) {
    // Remove existing listener
    touchInterceptor?.removeTouchInterceptorFromViewPager()
    // Create a new listener with updated settings
    noSwipeListener = NoSwipeItemTouchListener(
        currentpostion,
        requireContext(),
        disableUpScroll = up,
        disableDownScroll = down
    )
    touchInterceptor.addTouchInterceptorToViewPager(noSwipeListener)
}

override fun onDestroy() {
    super.onDestroy()
    RecrodTypeManager.setUserFeed("play")
    touchInterceptor?.removeTouchInterceptorFromViewPager()
    touchInterceptor == null
}

2 拦截器,重点就是 move方法里的,我要获取 rv.scrollToPosition(position)
,这个方法在你向下滑动后,如果突然向上滑动,我们要进行拦截,不然此时快速切换,是可以滑动到下一个item的,我们要滑动回当前位置。这个是重点
class NoSwipeItemTouchListener(
private val position: Int,
context: Context,
private val disableUpScroll: Boolean = false,
private val disableDownScroll: Boolean = false
) : RecyclerView.OnItemTouchListener {

//    private var startY = 0f
private val threshold = 5 // 滑动阈值,根据需要调整

private var startX = 0f
private var startY = 0f
private var lastX = 0f
private var lastY = 0f

private var diffY = 0f
override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}

override fun onInterceptTouchEvent(rv: RecyclerView, event: MotionEvent): Boolean {
    when (event.action) {
        MotionEvent.ACTION_DOWN -> {

// startY = e.y

            startX = event.x
            startY = event.y
            lastX = startX
            lastY = startY
        }

        MotionEvent.ACTION_MOVE -> {
            val currentX = event.x
            val currentY = event.y
            val diffX = currentX - lastX
            diffY = currentY - lastY

            if (Math.abs(diffX) > threshold || Math.abs(diffY) > threshold) {
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    // 左右滑动
                    if (diffX > 0) {
                        onSwipeRight()
                    } else {
                        onSwipeLeft()
                    }
                } else {
                    // 上下滑动
                    if (diffY > 0) {

// LogUtil.d("diffY", "diffY: diffY") onSwipeDown() //如果向下滑动禁止了 则拦截这个事件 if (!disableDownScroll) { return true } } else { onSwipeUp() LogUtil.d("diffY", "diffY:diffY")
//如果向上滑动禁止了 则拦截这个事件 ,并且回到原位
if (!disableUpScroll) {
if (diffY<-5){
rv.scrollToPosition(position)
LogUtil.d("scrollToPosition", "scrollToPosition")
}
return true
}
}
}

                // 更新lastX和lastY以适应连续滑动
                lastX = currentX
                lastY = currentY
            }
        }

        MotionEvent.ACTION_UP,MotionEvent.ACTION_CANCEL -> {
            // 结束时重置状态
            startX = 0f
            startY = 0f
            lastX = 0f
            lastY = 0f
        }
    }
    return false
}

private fun onSwipeRight() {
    LogUtil.d("SwipeDirection", "Detected right")
    // 处理向右滑动逻辑
}

private fun onSwipeLeft() {
    LogUtil.d("SwipeDirection", "Detected left")
    // 处理向左滑动逻辑
}

private fun onSwipeUp() {
    LogUtil.d("SwipeDirection", "Detected up")
    // 处理向上滑动逻辑
}

private fun onSwipeDown() {
    LogUtil.d("SwipeDirection", "Detected down")
    // 处理向下滑动逻辑
}

override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}

}

3 viewpager2 设置每一个item的监听方法
class ViewPagerTouchInterceptor(private val viewPager: ViewPager2?) {

private var recyclerView: RecyclerView? = null
private var listener: RecyclerView.OnItemTouchListener? = null

init {
    recyclerView = getRecyclerViewFromViewPager(viewPager)
}

private fun getRecyclerViewFromViewPager(viewPager: ViewPager2?): RecyclerView? {
    for (i in 0 until (viewPager?.childCount ?: 0)) {
        val child = viewPager?.getChildAt(i)
        if (child is RecyclerView) {
            return child
        }
    }
    return null
}

fun addTouchInterceptorToViewPager(listener: RecyclerView.OnItemTouchListener) {
    this.listener = listener
    recyclerView?.addOnItemTouchListener(listener)
}

fun removeTouchInterceptorFromViewPager() {
    listener?.let {
        recyclerView?.removeOnItemTouchListener(it)
    }
}

}

4 里面的getviewpager是我项目里的实例,自己自行替换即可

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容