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

Android RecyclerView如何检测OverScroll?重写onOverScrolled无效求助

解决RecyclerView重写onOverScrolled()不触发的问题

我之前也踩过这个坑!你重写onOverScrolled()后没触发,大概率是触发条件没满足,或者滚动事件被其他组件拦截了,下面给你一步步排查和解决:

先确认触发前提

onOverScrolled()不是只要RecyclerView到边界就会触发,只有当列表已经滚动到顶部/底部,并且你继续拖拽(或者惯性滚动)导致过度滚动时才会调用。所以先检查:

  • 你的列表数据是否足够多,能让RecyclerView出现垂直滚动条?如果列表内容没填满屏幕,根本不会触发滚动,更别说过度滚动了。
  • 你是否真的拖拽到了边界之外?比如列表到顶部后,继续往下拉一段距离,而不是仅仅停在顶部。

排查嵌套滚动拦截问题

如果你的RecyclerView嵌套在CoordinatorLayout、NestedScrollView这类支持嵌套滚动的容器里,滚动事件可能被父容器拦截,导致onOverScrolled()接收不到。这时候可以试试禁用RecyclerView的嵌套滚动:

recyclerView.setNestedScrollingEnabled(false);

设置后再测试过度滚动,看Toast是否弹出。

替代方案:用OnOverScrollListener(API 23+)

如果重写onOverScrolled()还是不行,从Android 6.0(API 23)开始,RecyclerView提供了更直接的OnOverScrollListener,专门用来监听过度滚动事件,用法更简单:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    recyclerView.setOnOverScrollListener(new RecyclerView.OnOverScrollListener() {
        @Override
        public void onOverScrolled(@NonNull RecyclerView recyclerView, int dx, int dy, boolean isTouchEvent) {
            super.onOverScrolled(recyclerView, dx, dy, isTouchEvent);
            // dy为负:顶部过度滚动;dy为正:底部过度滚动
            String tip = dy < 0 ? "顶部过度滚动" : "底部过度滚动";
            Toast.makeText(recyclerView.getContext(), tip, Toast.LENGTH_SHORT).show();
        }
    });
}

兼容低版本的方案:OnScrollListener结合边界判断

如果需要兼容API 23以下的设备,可以用OnScrollListener结合canScrollVertically()来判断是否到达边界,再结合滚动状态检测过度滚动:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        // 只有在拖拽或惯性滚动状态下,才检测过度滚动
        if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) {
            boolean isAtTop = !recyclerView.canScrollVertically(-1); // 不能向上滚动,说明在顶部
            boolean isAtBottom = !recyclerView.canScrollVertically(1); // 不能向下滚动,说明在底部

            if (isAtTop) {
                Toast.makeText(recyclerView.getContext(), "顶部过度滚动", Toast.LENGTH_SHORT).show();
            }
            if (isAtBottom) {
                Toast.makeText(recyclerView.getContext(), "底部过度滚动", Toast.LENGTH_SHORT).show();
            }
        }
    }
});

最后再检查你的代码

你的自定义RecyclerView代码本身没有问题,但要确保:

  • 布局中确实使用了MyRecyclerView,而不是系统默认的RecyclerView
  • 已经正确设置了recyclerView.setOverScrollMode(View.OVER_SCROLL_ALWAYS)(这个你已经做了)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:51:17