过去2天,我一直在与RecyclerView作战。与过去的任何时候不同,我希望滑动以关闭功能。
我关注了 this guide
我在这里实现的唯一区别是,我没有API响应来填充数据,而不是使用预定义的数组进行输入。一切似乎都很好,当我打开recyclerview时,项目将按原样填充。按照他们应该的顺序。
从这里开始乐趣。如果我尝试滑动以消除第一项,则会出现IndexOutOfBounds错误。太可爱了,搜索后发现我发现有人选择根据第一个列表设置一个新列表,删除该项目,然后将原始列表重新分配给新列表。完成后notifyDataSetChanged()。没有更多的错误,但是没有回收站视图的动画,无法将第二项带到列表的顶部。任何时候调用notifyDataSetChanged()时,列表都不会移动。我向下滚动并向上备份,项目又回来了。还是我想。
玩了一段时间后,我注意到虽然第一项中的信息似乎是原始的第一项,但它在列表中具有第二项的ID,而视图中的最后一项现在丢失了
这里是一个例子:
我从列表中滑动1,这就是用户界面显示的内容
很多代码要嵌入此处,并且尝试这样做会引发错误,要旨在https://gist.github.com/baggednismo/2840d0f777438d29673bc29096153970
答案 0 :(得分:0)
尝试从适配器中删除setHasStableIds(true)
和覆盖的getItemId()
。
您要告诉RecyclerView
,第n个 视图将始终表示列表中的同一项,并且删除其中一项会感到不高兴。
(I只是试图用非常简化的例子setHasStableIds(true)
,并得到了类似的例外;它工作得很好,当我除去它和getItemId()
)
请注意,调用notifyItemDeleted()
优于替换整个列表,但是如果您确实希望或需要替换整个列表,则应考虑使用DiffUtil
来确定并做出适当的选择更改为列表,如果仍然存在相同的项目,它将执行所有很酷的动画。
如果你想看到我的例子,它在https://gist.github.com/javadude/dec1862b075338790f023b42e01fd953(但它在科特林)
答案 1 :(得分:0)
@Scott Stanchfield的输入非常正确。他的评论和答案中指出的变化清除了视图,以帮助我找到与视图相关的实际问题。这些建议仍在实施中,并且是解决方案的一部分。
onBindViewHolder()创建的项目视图是基于原始API响应订单而不是列表订单recyclerview正在处理的订单项创建的。每当滚动条列表中出现一个新项时,就会调用onBindViewHolder(),这就是问题所在。在列表的第一个膨胀上,此方法就可以正常工作,但是,一旦删除该项目并滚动回到顶部,则第一个项目似乎是被撤消的项目。
原文:
KitchenOrdersResponse.Item mItem = mKitchenOrdersResponse.getItems().get(i);
分辨率:
KitchenOrdersResponse.Item mItem = mItems.get(i);