0

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 CardApaterRecyclerView.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.

+1

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

+1

get it! danke für den Hinweis – daco

+0

Sollte ich es eine Antwort machen, die Sie annehmen werden? – Pavlos

Antwort

0

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.