从 RecyclerView 中删除卡片并重新添加

Deleting Card from RecyclerView and re-add it again

我正在努力实现删除 recyclerview 的条目并重新添加它的功能,如果用户另有决定的话。为此,我展示了一个带有撤消操作的 Snackbar

所以流程应该是:用户看到 Cards 的列表,每个列表显示一些值和一个删除按钮。如果用户按下删除按钮,卡片将被删除并显示 Snackbar。如果用户在 Snackbar 上单击撤消,则 Card 应该重新添加到 RecyclerView。只有当 Snackbar 超时消失时,相应的条目也应该从 SQLite 数据库中删除。

我正在填充相应 CardsTextViews 并在 onBindViewHolder 中设置删除按钮的 OnClickListener

我的 class CardApater 扩展 RecyclerView.Adapter<CardAdapter.CardViewHolder> 看起来像下面这样:

private List<CardEntry> cards;

public CardAdapter(List<CardEntry> cards) {
    this.cards = cards;
}


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

@Override
public void onBindViewHolder(final CardViewHolder cardViewHolder, int i) {
    final CardEntry card = cards.get(i);

    cardViewHolder.tvDate.setText(card.date);
    cardViewHolder.tvValue1.setText(card.value1);
    cardViewHolder.tvValue2.setText(card.value2);
    cardViewHolder.tvValue3.setText(card.value3);

    cardViewHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            cards.remove(cardViewHolder.getAdapterPosition());
            notifyDataSetChanged();


            Snackbar snack = Snackbar.make(view, "Deleted", Snackbar.LENGTH_LONG);
            snack.setAction("Undo", this);
            snack.setActionTextColor(Color.RED);

            snack.setCallback(new Snackbar.Callback() {
                @Override
                public void onDismissed(Snackbar snackbar, int event) {
                    super.onDismissed(snackbar, event);
                    switch (event) {
                        case DISMISS_EVENT_ACTION:
                            cards.add(card);
                            notifyDataSetChanged();
                            break;
                        case DISMISS_EVENT_TIMEOUT:
                            MainActivity.datasource.deleteSQLiteEntry(card.id);
                            break;
                    }
                }
            });

            snack.show();

        }
    });
}

@Override
public CardViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View itemView = LayoutInflater.
            from(viewGroup.getContext()).
            inflate(R.layout.cardview, viewGroup, false);

    return new CardViewHolder(itemView);
}

public static class CardViewHolder extends RecyclerView.ViewHolder {

    protected TextView tvDate;
    protected TextView tvValue1;
    protected TextView tvValue2;
    protected TextView tvValue3;
    protected ImageView deleteButton;

    public CardViewHolder(View v) {
        super(v);
        tvDate =  (TextView) v.findViewById(R.id.date);
        tvValue1 = (TextView)  v.findViewById(R.id.value1);
        tvValue2 = (TextView) v.findViewById(R.id.value2);
        tvValue3 = (TextView) v.findViewById(R.id.value3);
        deleteButton = (ImageView) v.findViewById(R.id.delete);
    }
}

删除卡片有效,但是当将 CardEntry 重新添加到列表时,应用程序崩溃并在 onClick 方法的 cards.remove(cardViewHolder.getAdapterPosition()); 行出现 ArrayIndexOutOfBoundsException: length=12; index=-1

如有任何建议或添加新条目时为何调用 onClick,我们将不胜感激。

这可能是因为回收。移除卡的适配器位置,当前指向任何内容。您应该将该位置保留在 onBindViewHolder 的范围之外,并使用该位置重新添加它。