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

滑动子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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 03:57:13