解决方案 - 希望这将有助于某些人
我找到了这个的原因.如果有人试图从他的数组列表中动态删除元素,并且notifyItemRemoved(position)
不发送单击的位置作为参数onBindViewHolder(ViewHolder holder, int position)
.你将遇到与我完全相同的情况.
如果你在列表fe中有4个显示的元素[0, 1, 2, 3]
并尝试从列表的末尾删除一切都会很好,因为clicked positions
将完全相同positions in ArrayList
.例如,如果单击第4个元素:
position = 3
- 单击列表元素时将获得的位置; myArray.remove(position)
- 将使用index = 3
和删除元素notifyItemRemoved(position)
- 将为列表设置动画并从显示的列表中删除已删除的元素.您将拥有以下列表:[0, 1, 2]
.这可以.
当您要删除随机元素时,情境会发生变化.假设我要删除第3个显示的列表元素.我点击它删除所以我得到:
position = 2
- > myArray.remove(position)
- >notifyItemRemoved(position)
在这种情况下,我将得到的ArrayList将是这样的:[0, 1, 3]
.在我现在点击最后一个dispalyed元素,并希望删除它,这将是我将得到的:
position = 3
- > myArray.remove(position)
- >notifyItemRemoved(position)
但是会发生什么?应用突然崩溃,但异常:java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
.这意味着我们试图将元素放在不存在的位置.但为什么?我从元素中点击了我的位置......这就是发生的事情:
At the beggining we had:
ARRAY列表索引 - > [0, 1, 2, 3]
点击的位置 - > [0, 1, 2, 3]
After Deleting 3rd element:
ARRAY列表索引 - > [0, 1, 2]
点击的位置 - > [0, 1, 3]
现在,当我尝试删除元素时,position = 3
我们无法做到这一点.我们没有那个职位.我们可以得到的最大位置是2
.这就是为什么我们得到例外.如何管理这个问题?
在onBindViewHolder(ViewHolder holder, int position)
我们使用position
在
removeFromFavourites(position)
.但是我们也回来了holder
.如果我们使用被称为的方法:getAdapterPosition()
从课堂上RecyclerView.ViewHolder
我们在家.
getAdapterPosition
来自开发者网站:http://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#getAdapterPosition()
这将始终返回与中的索引相同的索引ArrayList
.因此总结我们所要做的就是改变position
参数holder.getAdapterPosition()
:
// Binding New View @Override public void onBindViewHolder(ViewHolder holder, int position) { RecipeItem item = items.get(position); // Binding Recipe Image Picasso.with(context).load(item.getImgThumbnailLink()).into(holder.recipeItemImage); // Binding Recipe Title holder.recipeItemTitle.setText(item.getTitle()); // Binding Recipe Subtitle String subtitle = "Kuchnia " + item.getKitchenType() + ", " + item.getMealType(); holder.recipeItemSubtitle.setText(subtitle); // Binding Recipe Likes Count holder.recipeItemLikesCount.setText(Integer.toString(item.getLikeCount())); // Binding Recipe Add Date holder.recipeItemAddDate.setText(item.getAddDate()); // Binding Recipe Options Icon holder.recipeItemOptionsIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { PopupMenu popupMenu = new PopupMenu(context, v); setPopUpListener(popupMenu, holder.getAdapterPosition()); // Setting Popup Listener inflatePopupMenu(popupMenu); // Inflating Correct Menu popupMenu.show(); } }); // Item Click Listener holder.setClickListener(new RecipeItemClickListener() { @Override public void onClick(View view, int position) { // taking to recipe activity } }); }