解决方案 - 希望这会对某人有所帮助
我已经找到了解决方案。如果有人尝试动态地从他的数组列表中删除元素并且notifyItemRemoved(position)
不要发送点击位置作为内部参数onBindViewHolder(ViewHolder holder, int position)
。你会遇到和我一模一样的情况。
如果列表中有 4 个显示元素,例如[0, 1, 2, 3]
并尝试从列表末尾删除一切都会好的原因clicked positions
将匹配完全相同positions in ArrayList
。例如,如果您单击第四个元素:
position = 3
- 单击列表元素时将获得的位置;myArray.remove(position)
- 将删除元素index = 3
and notifyItemRemoved(position)
- 将对列表进行动画处理并从显示的列表中删除已删除的元素。您将有以下列表:[0, 1, 2]
。这可以。
当您想要删除随机元素时,情况会发生变化。假设我想删除第三个显示的列表元素。我点击它来删除,所以我得到:
position = 2
-> myArray.remove(position)
-> notifyItemRemoved(position)
在这种情况下,我将得到的 ArrayList 将如下所示:[0, 1, 3]
。现在,我单击最后一个显示的元素并想删除它,这就是我将得到的:
position = 3
->myArray.remove(position)
-> notifyItemRemoved(position)
但会发生什么呢?应用程序突然崩溃并出现异常:java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3
。这意味着我们正在尝试获取不存在位置的元素。但为什么?我从元素中获取了点击位置...这就是发生的事情:
At the beggining we had:
数组列表索引 ->[0, 1, 2, 3]
点击位置 ->[0, 1, 2, 3]
After Deleting 3rd element:
数组列表索引 ->[0, 1, 2]
点击位置 ->[0, 1, 3]
现在,当我尝试删除元素时position = 3
我们不能那样做。我们没有这个立场。我们能得到的最大位置是2
。这就是我们得到例外的原因。如何解决这个问题?
In onBindViewHolder(ViewHolder holder, int position)
我们用了position
in
removeFromFavourites(position)
。但我们也有我们的回报holder
。如果我们使用名为的方法:getAdapterPosition()
从课堂上RecyclerView.ViewHolder
我们在家。
getAdapterPosition
来自开发者网站:http://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder.html#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
}
});
}