Android 添加项后,Recyclerview将索引绑定到列表大小之外
我有一个回收站的经理。我的方法Android 添加项后,Recyclerview将索引绑定到列表大小之外,android,scroll,android-recyclerview,indexoutofboundsexception,Android,Scroll,Android Recyclerview,Indexoutofboundsexception,我有一个回收站的经理。我的方法addItems()从Internet下载数据,然后依次添加10项,如下所示: itemIds.add(id); listAdapter.notifyItemInserted(itemIds.size() - 1); 当活动启动并且用户滚动到(大小-3)时,我调用此方法: 因此,RecyclerView希望将旧位置7的ViewHolder重新用于新位置27,但该位置当然不存在 为了进行调试,我添加了一个自定义类,扩展了LinearLayoutManager,以防止
addItems()
从Internet下载数据,然后依次添加10项,如下所示:
itemIds.add(id);
listAdapter.notifyItemInserted(itemIds.size() - 1);
当活动启动并且用户滚动到(大小-3)时,我调用此方法:
因此,RecyclerView希望将旧位置7的ViewHolder重新用于新位置27,但该位置当然不存在
为了进行调试,我添加了一个自定义类,扩展了LinearLayoutManager,以防止因IndexOutfBoundsException而崩溃:
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
try {
super.onLayoutChildren(recycler, state);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
然后我的列表就完美地工作了——新的项目被平滑地添加到列表中,甚至多次,因此它会产生一个无限的列表。Logcat中只有这个小堆栈跟踪
我觉得用try/catch忽略这个IndexOutOfBoundsException是不对的,因为它实际上对catch没有任何作用。有人知道如何修复这个奇怪的位置吗
编辑:在测试了不同的项目大小后,我发现Recyclerview总是希望在此位置加载项目:
+2*
当然,它总是超出总列表大小。看起来您必须使用此方法
listAdapter.notifyItemRangeInserted(startPosition,itemCount)代码>
notifyItemInserted(位置)
仅用于插入一项。如果要插入多个项目,必须使用notifyItemRangeInserted(position,itemCount)
您是否会使用此方法插入所有10项,而不是在循环中逐个添加,并检查是否得到相同的异常 除了Dinesh Bob所说的之外,我认为您的代码没有任何问题。我将在RecyclerView中发布如何实现分页:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount=linearLayoutManager.getChildCount();
int totalItemCount=linearLayoutManager.getItemCount();
int firstVisibleItemPosition=linearLayoutManager.findFirstVisibleItemPosition();
if(!isPageLoading && !isLastPage)
{
if((visibleItemCount + firstVisibleItemPosition)>=totalItemCount)
{
offset+=limit;
loadMoreItems(offset);
}
}
}
});
loadMoreItems继续并进行API调用,然后将这些项添加到适配器中,如下所示:
public void addAllItems(List<Item> itemList)
{
for(Item itemRow: itemList)
{
this.itemList.add(itemRow);
notifyItemInserted(this.itemList.size() - 1);
}
}
public void addAllItems(列表项列表)
{
对于(项目行:项目列表)
{
this.itemList.add(itemRow);
notifyItemInserted(this.itemList.size()-1);
}
}
由于ListView中存在错误,在使用ListView时实现分页时,捕获异常的块是必需的。但是回收站不需要它
也会给你的代码一个机会,看看它到底出了什么问题 之所以发生这种情况,是因为您正在向列表中添加数据,同时在通知recyclerview的适配器之前尝试滚动它
所以,当您在第7位之后加载数据时,请执行此操作
mData.add(yourdata);
mAdapter.notifyDataSetChanged();
如果您将继续添加数据并继续滚动它。它将为您提供“检测到不一致性”错误。因为adapter认为只有7项,当您滚动时,它变成了10项,而adaper没有收到通知。谢谢您的回答,但不幸的是,错误仍然存在。您可以共享适配器的基本版本吗?一开始你有10个项目,当你达到第7个项目时,你会加载更多+10个项目,对吗?没错。适配器仅将列表大小返回为itemcount,并具有正常的创建和绑定函数,我认为这与此问题无关。谢谢,您的代码与我的代码几乎相同–我切换到firstVisibleItemPosition而不是lastVisible,并使用linearLayoutManager.getChildCount()而不是adapter.getChildCount(),但是错误仍然存在。将notifyItemInserted(…)
替换为notifyDataSetChanged()
对我来说成功了!不知道为什么,因为notifyItemInserted
实际上更具体,因此更好,但无论如何,感谢您的正确答案!(PS:mAdapter.updateData(mData);
在我看来是不需要的,因为适配器和我的活动都引用了保存所有数据项的同一个列表对象。)
public void addAllItems(List<Item> itemList)
{
for(Item itemRow: itemList)
{
this.itemList.add(itemRow);
notifyItemInserted(this.itemList.size() - 1);
}
}
mData.add(yourdata);
mAdapter.notifyDataSetChanged();