Ich habe Schwierigkeiten, die Funktionalität zu implementieren, um einen Eintrag einer Recycleransicht zu löschen und erneut hinzuzufügen, wenn der Benutzer anders entschieden hat. Dafür zeige ich eine Snackbar
mit einer rückgängig machenden Aktion.Karte aus RecyclerView löschen und erneut hinzufügen
So sollte der Ablauf sein: Der Benutzer sieht eine Liste von Cards
, die jeweils einige Werte und eine Schaltfläche zum Löschen zeigen. Wenn der Benutzer die Löschtaste drückt, wird die Karte gelöscht und Snackbar
wird angezeigt. Wenn der Benutzer auf die Snackbar
rückgängig klickt, sollte die Card
wieder zu der RecyclerView
hinzugefügt werden. Nur wenn die Snackbar
durch Timeout verschwindet, sollte der entsprechende Eintrag auch aus der Datenbank SQLite
gelöscht werden.
ich bevölkern die TextViews
des jeweiligen Cards
und die OnClickListener
der Löschtaste in onBindViewHolder
gesetzt.
Meine Klasse CardApater
RecyclerView.Adapter<CardAdapter.CardViewHolder>
erstreckt sieht aus wie der 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);
}
}
die Karte funktioniert löschen, aber beim erneuten Hinzufügen der CardEntry auf die Liste, die App stürzt mit ArrayIndexOutOfBoundsException: length=12; index=-1
an der Linie cards.remove(cardViewHolder.getAdapterPosition());
im onClick
Verfahren .
Alle Vorschläge dazu oder warum onClick
wird überhaupt aufgerufen, wenn ein neuer Eintrag hinzugefügt wird.
Dies könnte auf das Recycling zurückzuführen sein. Die Adapterposition der entfernten Karte zeigt momentan nichts an. Sie sollten die Position außerhalb des Bereichs von onBindViewHolder behalten und diese verwenden, um sie erneut hinzuzufügen. – Pavlos
get it! danke für den Hinweis – daco
Sollte ich es eine Antwort machen, die Sie annehmen werden? – Pavlos