Wenn Sie stabile IDs in Ihrem Adapter haben, können Sie ziemlich gute Ergebnisse (Animationen), wenn Sie ein neues Array erstellen, die gefilterten Elemente enthält und rufen
recyclerView.swapAdapter(newAdapter, false);
Mit swapAdapter Hinweise RecyclerView, dass es View Holders erneut verwenden (vs in SetAdapter, muss es alle Ansichten recyceln und neu erstellen, da es nicht weiß, dass der neue Adapter den gleichen ViewHolder mit dem alten Adapter festgelegt hat).
Ein besserer Ansatz wäre, herauszufinden, welche Elemente entfernt werden und notifyItemRemoved(index)
aufrufen. Vergessen Sie nicht, den Artikel tatsächlich zu entfernen. Dadurch kann RecyclerView prädiktive Animationen ausführen. Vorausgesetzt, dass Sie einen Adapter haben, die intern eine Arraylist verwendet, würde die Umsetzung wie folgt aussehen:
// adapter code
final List<ItemData> mItems = new ArrayList(); //contains your items
public void filterOut(String filter) {
final int size = mItems.size();
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
notifyItemRemoved(i);
}
}
}
Es wäre noch mehr leisten, wenn Sie können Batch notifyItemRemoved
Anrufe und verwenden notifyItemRangeRemoved
statt. Es würde aussehen etw wie: (nicht getestet)
public void filterOut(String filter) {
final int size = mItems.size();
int batchCount = 0; // continuous # of items that are being removed
for(int i = size - 1; i>= 0; i--) {
if (mItems.get(i).test(filter) == false) {
mItems.remove(i);
batchCount ++;
} else if (batchCount != 0) { // dispatch batch
notifyItemRangeRemoved(i + 1, batchCount);
batchCount = 0;
}
}
// notify for remaining
if (batchCount != 0) { // dispatch remaining
notifyItemRangeRemoved(0, batchCount);
}
}
Sie müssen diesen Code erweitern Elemente hinzufügen, die zuvor herausgefiltert wurden, aber jetzt sollte sichtbar sein (zB Benutzer löscht die Filterabfrage), aber ich denke, das sollte man geben Sie die Grundidee.
Denken Sie daran, dass jeder Benachrichtigungs-Item-Aufruf die nachfolgenden betrifft (weshalb ich die Liste von Ende an durchquere, um sie zu vermeiden). Traversing from End hilft auch ArrayList beim Entfernen der Methodenleistung (weniger Elemente zum Verschieben).
Zum Beispiel, wenn Sie die Liste von Anfang an durchlaufen und die ersten beiden Elemente entfernen. Sie sollten entweder rufen
notifyItemRangeRemoved(0, 2); // 2 items starting from index 0
oder wenn Sie ihnen ein Versand von einem
notifyItemRemoved(0);
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0
Wenn Sie ein anderes Array geben, möchten Sie einfach erstellen können neu 'ItemsAdapter' mit ihm und rufen' wieder setAdapter'. –