创建分页滚动到底RecyclerView时onScrolled回调完全未触发求助
嘿,我一眼就盯上你代码里的setNestedScrollingEnabled(false)了——这几乎肯定是onScrolled回调没触发的核心原因!
问题根源
当你禁用RecyclerView的嵌套滚动后,它的滚动事件会被父容器(比如NestedScrollView这类可滚动容器)拦截,导致RecyclerView自身的OnScrollListener完全接收不到滚动信号。很多人会为了让RecyclerView在NestedScrollView里能正常滚动而加这行代码,但这恰恰会牺牲掉RecyclerView的滚动监听能力。
修复步骤
移除禁用嵌套滚动的代码
直接删掉mBooksRecyclerView.setNestedScrollingEnabled(false);这一行。如果你的RecyclerView是放在NestedScrollView里导致滚动异常,那换个方案:给NestedScrollView添加android:fillViewport="true"属性,同时把RecyclerView的高度设为wrap_content,这样既能保证滚动流畅,又能让RecyclerView的滚动监听正常工作。确认LayoutManager已正确设置
别忘给RecyclerView设置LayoutManager!没有LayoutManager的话,RecyclerView根本不会有滚动行为,自然触发不了onScrolled。比如:mBooksRecyclerView.setLayoutManager(new LinearLayoutManager(this));修改后的完整代码示例
// 先设置LayoutManager(这步绝对不能少!) mBooksRecyclerView.setLayoutManager(new LinearLayoutManager(this)); // 添加滚动监听,现在应该能正常触发onScrolled了 mBooksRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); Log.i("Dale", "scrolled"); // 这里可以继续实现分页加载逻辑,比如判断是否滚动到底部 LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int visibleItemCount = layoutManager.getChildCount(); int totalItemCount = layoutManager.getItemCount(); int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition(); // 当滚动到底部且向上滚动时,触发加载更多 if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount && firstVisibleItemPosition >= 0 && dy > 0) { loadMoreBooks(); // 你的分页加载方法 } } }); if (Utils.hasContent(books)) { mBooksRecyclerView.setVisibility(View.VISIBLE); BookCardViewAdapter adapter = new BookCardViewAdapter(books); mBooksRecyclerView.setAdapter(adapter); }
特殊场景处理
如果因为某些需求必须禁用嵌套滚动,那你可以给父滚动容器添加滚动监听,在父容器的滚动回调里判断是否到达底部,再触发分页加载。不过这种方式不如直接用RecyclerView自身的监听来得直观和方便,还是优先推荐上面的方案。
内容的提问来源于stack exchange,提问作者Dale Julian

