Endless RecyclerView问题:仅能加载一次数据求助
看起来你遇到了Endless RecyclerView的典型问题——只能加载第二页,之后就没反应了。结合你贴的代码和调试发现的adapter.setLoadMore()只触发一次的情况,我帮你梳理几个核心问题点和修复方案:
核心问题分析
1. 错误的加载触发限制条件
你的onLoadMore方法开头有个判断:
if (postItems.size() <= count) { // 加载逻辑 }
这里的count应该是单页数据量吧?比如第一页加载10条,postItems.size()等于count,满足条件加载第二页;第二页加载后postItems.size()变成20,这时候20 > count,这个判断就不成立了,直接跳过后续的加载逻辑——这就是为什么只能加载第二页的关键原因!
2. isLoading状态重置时机错误
你在onLoadMore里,刚触发延迟任务就立刻调用了adapter.setLoaded():
new Handler().postDelayed(new Runnable() { @Override public void run() { // 数据加载逻辑 } }, 2000); adapter.setLoaded();
这会导致isLoading提前被设为false,但此时数据还在加载中,可能引发滚动监听的混乱,甚至干扰后续加载触发逻辑。
3. 加载完成后的状态重置位置不对
你应该在数据成功加载并更新到列表之后再调用adapter.setLoaded(),而不是在启动异步任务之前。
具体修复步骤
步骤1:移除错误的限制条件
把onLoadMore里的postItems.size() <= count判断去掉,直接用counter <= pages来控制是否还有更多页可以加载:
adapter.setLoadMore(new ILoadMore() { @Override public void loadMore() { // 去掉postItems.size() <= count的判断 if (counter <= pages) { postItems.add(null); adapter.notifyItemInserted(postItems.size() - 1); new Handler().postDelayed(new Runnable() { @Override public void run() { postItems.remove(postItems.size() - 1); counter += 1; Log.d("HAHAHAHA", "onScrolled: End " + counter); Log.d("HAHAHAHA", "onScrolled: Counter: " + counter); getData(counter); // 发起数据请求 } }, 2000); } else { Toast.makeText(getContext(), "Done", Toast.LENGTH_SHORT).show(); adapter.setLoaded(); // 没有更多数据,重置加载状态 } } });
步骤2:调整setLoaded()的调用时机
修改你的getData方法,在数据成功解析并添加到postItems之后再调用adapter.setLoaded(),确保只有当数据真正准备好时,才允许下一次加载:
private void getData(int page) { // 这里是你的网络请求逻辑,比如Retrofit/Volley请求 // 假设请求成功的回调里: List<PostItem> newItems = parseJsonFromResponse(response); // 解析JSON得到新数据 postItems.addAll(newItems); adapter.notifyDataSetChanged(); // 更新列表 adapter.setLoaded(); // 现在才重置加载状态,允许下一次触发 }
步骤3:验证滚动监听的触发条件
检查Adapter里的visibleThreshold值,建议设为1或2(表示距离底部还有1/2个item时触发加载),同时确保isLoading的初始值是false。另外,在滚动监听里添加日志,确认每次滚动时的参数:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); totalItemCount = manager.getItemCount(); lastVisibleItem = manager.findLastVisibleItemPosition(); // 添加日志,查看每个参数的值 Log.d("SCROLL_DEBUG", "isLoading: " + isLoading + " | totalItemCount: " + totalItemCount + " | lastVisibleItem+threshold: " + (lastVisibleItem + visibleThreshold)); if(!isLoading && totalItemCount <= (lastVisibleItem + visibleThreshold)) { Log.d("HAHAHAHA", "onScrolled: Trigger load more"); loadMore.loadMore(); isLoading = true; } } });
额外检查点
- 确认
counter的初始值:如果第一页是counter=1,那加载第二页后counter=2,以此类推,确保pages是正确的总页数(比如从接口返回的总页数)。 - 检查
getData方法是否正确请求了对应页码的数据,避免页码传递错误导致返回空数据,进而没有触发后续加载。
内容的提问来源于stack exchange,提问作者Shantanu Patil

