滑动子RecyclerView时触发Activity的onRefresh()方法问题求助
解决嵌套RecyclerView触发SwipeRefreshLayout刷新的问题
当前问题出在无论子RecyclerView是否处于可滚动状态,都强制禁止父布局拦截触摸事件,逻辑应该调整为:只有当子RecyclerView已经滚动到顶部、无法继续向上滚动时,才允许SwipeRefreshLayout拦截触摸事件;否则禁止父布局拦截,避免误触发刷新。
可以通过以下两种方式修复:
方式一:优化现有OnItemTouchListener逻辑
修改onInterceptTouchEvent中的判断逻辑,根据子RecyclerView的滚动状态动态决定是否禁止父布局拦截:
val scrollTouchListener: RecyclerView.OnItemTouchListener = object : RecyclerView.OnItemTouchListener { override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean { when (e.action) { MotionEvent.ACTION_DOWN -> { // 按下时先让父布局不拦截,确保子RecyclerView能接收触摸事件 rv.parent.requestDisallowInterceptTouchEvent(true) } MotionEvent.ACTION_MOVE -> { // 判断子RecyclerView是否能向上滚动 val canScrollUp = rv.canScrollVertically(-1) // 如果能向上滚动,禁止父布局拦截;否则允许父布局拦截(触发SwipeRefresh) rv.parent.requestDisallowInterceptTouchEvent(canScrollUp) } MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { // 触摸结束时恢复父布局的拦截权限 rv.parent.requestDisallowInterceptTouchEvent(false) } } return false } override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {} override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {} } mBinding.childRecyclerView.addOnItemTouchListener(scrollTouchListener)
方式二:使用RecyclerView滚动监听器替代
相比OnItemTouchListener,使用addOnScrollListener更简洁,直接监听滚动状态:
mBinding.childRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) // 判断子RecyclerView是否处于顶部(无法向上滚动) val isAtTop = !recyclerView.canScrollVertically(-1) // 只有在顶部时,才允许SwipeRefreshLayout拦截触摸事件 mBinding.swipeRefreshLayout.isEnabled = isAtTop } })
关键说明
canScrollVertically(-1):判断RecyclerView是否能向上滚动,返回true表示还有内容可以向上滑,false表示已经在顶部。- 方式二中直接控制SwipeRefreshLayout的启用状态,当子RecyclerView不在顶部时,禁用下拉刷新,从根源避免误触发。
内容的提问来源于stack exchange,提问作者kaushal
相关产品推荐
相关产品推荐

