【Android】RecyclerView纵向倾斜滑动,触发ViewPage2横向滑动而导致的滑动冲突问题

问题描述

场景ViewPage2+Fragment+RecyclerView(我的项目里RecycleView外层还套了一层SmartRefreshLayout)

因ViewPage2滑动太灵敏,RecyclerView纵向倾斜滑动,触发ViewPage2横向滑动而导致的滑动冲突问题

解决方案:

纵向倾斜滑动时,其实纵向、横向这两个动作都已触发了,在横向灵敏度高的情况下,可通过给横向滑动设置一个最小临界条件,控制横向滑动的触发条件,不至于横向滑动那么灵敏。

因我的子布局是SmartRefreshLayout+RecycleView,如果你的子布局就只有RecycleView,只需将我下面自定义的CustomRefreshLayout 类里的SmartRefreshLayout替换成RecycleView就行。

kotlin 复制代码
/**
 * 解决ViewPage2内嵌RecyclerView时,因ViewPage2滑动太灵敏,RecyclerView纵向倾斜滑动,
 * 触发ViewPage2横向滑动的滑动冲突问题
 */
class CustomRefreshLayout @JvmOverloads constructor(
    context: Context, 
    attrs: AttributeSet? = null, 
    defStyleAttr: Int = 0
) : SmartRefreshLayout(context, attrs, defStyleAttr) {

    private var startX = 0f
    private var startY = 0f
    companion object {
        const val MIN_DISTANCE = 100 // 设置一个最小滑动距离,以减少误判
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
                startX = ev.x
                startY = ev.y
                parent.requestDisallowInterceptTouchEvent(true) // 初始按下时,不让父控件拦截
            }
            MotionEvent.ACTION_MOVE -> {
                val endX = ev.x
                val endY = ev.y
                val disX = abs(endX - startX)
                val disY = abs(endY - startY)
                // 如果横向滑动距离大于纵向滑动距离,且大于设定的最小距离,则认为是水平滑动
                if (disX > disY) {
                    Log.e("dispatchTouchEvent 横向滑动:", "disX= $disX disY= $disY")
                    // 判断左右滑动的灵敏度,当左右滑动距离大于100 允许父控件处理滑动。
                    if (disX > MIN_DISTANCE) {
                        parent.requestDisallowInterceptTouchEvent(false)
                    }
                } else {
                    Log.e("dispatchTouchEvent 纵向滑动:", "disX= $disX disY= $disY")
                    // 纵向滑动,不让父控件拦截
                    parent.requestDisallowInterceptTouchEvent(true)
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                // 触摸事件结束时恢复默认行为
                parent.requestDisallowInterceptTouchEvent(false)
            }
        }
        return super.dispatchTouchEvent(ev)
    }
}
kotlin 复制代码
<CustomRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>
</CustomRefreshLayout>
相关推荐
lxysbly10 分钟前
md模拟器安卓版带金手指2026
android
儿歌八万首1 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节
消失的旧时光-19433 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs3 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&3 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH4 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android
冬奇Lab4 小时前
Android 15 ServiceManager与Binder服务注册深度解析
android·源码·源码阅读
2501_916008896 小时前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
独行soc7 小时前
2026年渗透测试面试题总结-20(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
常利兵7 小时前
2026年,Android开发已死?不,它正迎来黄金时代!
android