RecyclerView总是从视图中删除最后一个项目,并在位置0处删除项目时出错

时间:2019-02-02 02:54:18

标签: android android-recyclerview swipe

过去2天,我一直在与RecyclerView作战。与过去的任何时候不同,我希望滑动以关闭功能。

我关注了 this guide

我在这里实现的唯一区别是,我没有API响应来填充数据,而不是使用预定义的数组进行输入。一切似乎都很好,当我打开recyclerview时,项目将按原样填充。按照他们应该的顺序。

从这里开始乐趣。如果我尝试滑动以消除第一项,则会出现IndexOutOfBounds错误。太可爱了,搜索后发现我发现有人选择根据第一个列表设置一个新列表,删除该项目,然后将原始列表重新分配给新列表。完成后notifyDataSetChanged()。没有更多的错误,但是没有回收站视图的动画,无法将第二项带到列表的顶部。任何时候调用notifyDataSetChanged()时,列表都不会移动。我向下滚动并向上备份,项目又回来了。还是我想。

玩了一段时间后,我注意到虽然第一项中的信息似乎是原始的第一项,但它在列表中具有第二项的ID,而视图中的最后一项现在丢失了

这里是一个例子:

  1. text = Fox id = a
  2. text =狗id = b
  3. text =猪id = c

我从列表中滑动1,这就是用户界面显示的内容

  1. text = Fox id = b
  2. text =狗id = c

很多代码要嵌入此处,并且尝试这样做会引发错误,要旨在https://gist.github.com/baggednismo/2840d0f777438d29673bc29096153970

2 个答案:

答案 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);