Android - 从RecyclerView中删除元素会引发ConcurrentModificationException

时间:2017-09-02 16:22:19

标签: android android-recyclerview

我正在创建这个应用程序,我有一个带有一些图片的RecyclerView。如果用户想要删除其中一个,则他太长时间按下图片,并且图片顶部将显示灰色透明布局,其中" X"按钮删除图片。当用户按下" X"显示一个对话框,要求确认他是否接受该图片被删除。我不明白为什么我会收到" ConcurrentModificationException"当我接受删除图片时。标记的行是"返回data.size();" on method" getItemCount()",我没有访问"数据"从任何一方来看,我都能看到" getItemCount"被称为很多次。请注意,我删除了不必要的函数和类的成员。

public class RecyclerViewAdAdapter extends RecyclerView.Adapter<RecyclerViewAdAdapter.ViewHolder> {

private Context context;
private List<String> data;

public RecyclerViewAdAdapter(Context context, List<String> items) {
    this.context = context;
    this.data = items;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    View view = inflater.inflate(R.layout.grid_create_ad_item_layout, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    String imagePath = data.get(position);
    setImageBitmap(imagePath, holder.itemImage);
    holder.removeItemButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(context);
            builder.setMessage(R.string.confirm_remove_picture);
            builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    removeItem(holder.getAdapterPosition());
                }
            });
            builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            AlertDialog dialog = builder.create();
            dialog.setCancelable(true);
            dialog.show();
        }
    });
}

@Override
public int getItemCount() {
    return data.size();
}

private void removeItem(int position) {
    data.remove(position);
    notifyItemRemoved(position);
    notifyItemRangeChanged(position, data.size());
}

private void setImageBitmap(String item, ImageView imageView) {
    /***/
}

static class ViewHolder extends RecyclerView.ViewHolder {

    ImageView itemImage;
    RelativeLayout grayTopLayout;
    ImageView removeItemButton;

    ViewHolder(View itemView) {
        super(itemView);
        itemImage = (ImageView) itemView.findViewById(R.id.item_image);
        grayTopLayout = (RelativeLayout) itemView.findViewById(R.id.grayTopLayout);
        removeItemButton = (ImageView) itemView.findViewById(R.id.removeItemButton);

        itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                switch (grayTopLayout.getVisibility()) {
                    case View.VISIBLE:
                        v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                        grayTopLayout.setVisibility(View.GONE);
                        break;
                    case View.GONE:
                        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) v.getLayoutParams();
                        params.width = itemImage.getWidth();
                        v.setLayoutParams(params);
                        v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
                        grayTopLayout.setVisibility(View.VISIBLE);
                        break;
                    case View.INVISIBLE:
                        break;
                }
                return false;
            }
        });
    }
}

}

1 个答案:

答案 0 :(得分:1)

足够 notifyItemRemoved 方法。删除 notifyItemRangeChanged ,您的代码应该是这样的

private void removeItem(int position) {
data.remove(position);
notifyItemRemoved(position);
}

修改

而不是使用List使用CopyOnWriteArrayListCopyOnWriteArrayList阻止

ConcurrentModificationException