Se hai ids stabili nel vostro adattatore, è possibile ottenere buoni risultati (animazioni) se si crea un nuovo array contenente gli elementi filtrati e chiamare
recyclerView.swapAdapter(newAdapter, false);
Utilizzando swapAdapter suggerimenti RecyclerView che possa riutilizzare i detentori di immagini. (vs in setAdapter, deve riciclare tutte le viste e ricreare perché non sa che il nuovo adattatore ha lo stesso ViewHolder impostato con il vecchio adattatore).
Un approccio migliore sarebbe trovare quali elementi vengono rimossi e chiamando notifyItemRemoved(index)
. Non dimenticare di rimuovere effettivamente l'oggetto. Ciò consentirà a RecyclerView di eseguire animazioni predittive. Supponendo di avere un adattatore che utilizza internamente un ArrayList, implementazione sarebbe simile a questa:
// 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);
}
}
}
Si sarebbe eseguire ancora meglio se si può ammucchiare notifyItemRemoved
chiamate e utilizzare notifyItemRangeRemoved
invece. Sembrerebbe STH come: (non testato)
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);
}
}
È necessario estendere questo codice per aggiungere elementi che sono stati precedentemente filtrati, ma ora dovrebbe essere visibile (ad esempio utente elimina la query del filtro), ma penso che questo si dovrebbe dare l'idea di base.
Ricordare che ogni chiamata di elemento di notifica influisce su quelli successivi (motivo per cui sto attraversando l'elenco da fine per evitarlo). Attraversare da fine aiuta anche le prestazioni del metodo di rimozione di ArrayList (meno elementi da spostare).
Ad esempio, se si stava attraversando l'elenco dall'inizio e si rimuovono i primi due elementi. Si dovrebbe neanche chiamare
notifyItemRangeRemoved(0, 2); // 2 items starting from index 0
o se la spedizione uno per uno
notifyItemRemoved(0);
notifyItemRemoved(0);//because after the previous one is removed, this item is at position 0
Se si vuole dare un altro array si può semplicemente creare un nuovo 'ItemsAdapter' con esso e chiamare' setAdapter' di nuovo. –