Deleting Card from RecyclerView and re-add it again

∥☆過路亽.° 提交于 2021-01-29 05:34:21

问题


I'm struggling to implement the funtionality to delete an entry of a recyclerview and re-add it again, if the user decided otherwise. For that I'm showing a Snackbar with an undo action.

So the flow should be: The user sees a list of Cards which each show some values and an delete button. If the user presses the delete button, the card is deleted and a Snackbaris shown. If the user clicks undo on the Snackbar the Card should be re-added to the RecyclerView. Only if the Snackbar disappears by timeout, the respective entry should also be deleted from SQLite database.

I'm populating the TextViews of the respective Cards and set the OnClickListener of the delete button in onBindViewHolder.

My class CardApater extending RecyclerView.Adapter<CardAdapter.CardViewHolder> looks like the follwing:

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);
    }
}

Deleting the card works, but when re-adding the CardEntry to the list, the app crashes with ArrayIndexOutOfBoundsException: length=12; index=-1 at the line cards.remove(cardViewHolder.getAdapterPosition()); in the onClick method.

Any suggestions on that or why onClick is called at all when adding a new entry are appreciated.


回答1:


This might be because of recycling. The adapter position of the removed card, currently points to nothing. You should keep the position out of the scope of the onBindViewHolder and use that one to re-add it.



来源:https://stackoverflow.com/questions/36497691/deleting-card-from-recyclerview-and-re-add-it-again

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!