introduzione
Dal momento che non è davvero chiaro dalla tua domanda con cosa stai riscontrando esattamente problemi, ho scritto una breve guida su come implementare questa funzione; se hai ancora domande non esitare a chiedere.
Ho un esempio funzionante di tutto ciò di cui sto parlando qui in questo repository GitHub .
Se vuoi saperne di più sul progetto di esempio visita la pagina iniziale del progetto .
In ogni caso il risultato dovrebbe essere simile al seguente:
Se vuoi giocare per la prima volta con l'app demo, puoi installarla dal Play Store:
Comunque iniziamo.
Impostazione di SearchView
Nella cartella res/menu
creare un nuovo file chiamato main_menu.xml
. In esso aggiungere un elemento e impostare l' actionViewClass
a android.support.v7.widget.SearchView
. Poiché stai utilizzando la libreria di supporto, devi utilizzare lo spazio dei nomi della libreria di supporto per impostare l' actionViewClass
attributo. Il tuo file xml dovrebbe assomigliare a questo:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
Nel tuo Fragment
o Activity
devi gonfiare questo menu xml come al solito, quindi puoi cercare quello MenuItem
che contiene SearchView
e implementare quello OnQueryTextListener
che useremo per ascoltare le modifiche al testo inserito nel SearchView
:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
// Here is where we are going to implement the filter logic
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
E ora SearchView
è pronto per essere utilizzato. In seguito implementeremo la logica del filtro onQueryTextChange()
una volta terminata l'implementazione di Adapter
.
Impostazione di Adapter
Innanzitutto questa è la classe di modello che userò per questo esempio:
public class ExampleModel {
private final long mId;
private final String mText;
public ExampleModel(long id, String text) {
mId = id;
mText = text;
}
public long getId() {
return mId;
}
public String getText() {
return mText;
}
}
È solo il tuo modello di base che visualizzerà un testo in RecyclerView
. Questo è il layout che userò per visualizzare il testo:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="model"
type="com.github.wrdlbrnft.searchablerecyclerviewdemo.ui.models.ExampleModel"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@{model.text}"/>
</FrameLayout>
</layout>
Come puoi vedere, utilizzo il Data Binding. Se non hai mai lavorato prima con l'associazione dei dati, non scoraggiarti! È molto semplice e potente, tuttavia non riesco a spiegare come funzioni nell'ambito di questa risposta.
Questo è ViewHolder
per la ExampleModel
classe:
public class ExampleViewHolder extends RecyclerView.ViewHolder {
private final ItemExampleBinding mBinding;
public ExampleViewHolder(ItemExampleBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
public void bind(ExampleModel item) {
mBinding.setModel(item);
}
}
Ancora niente di speciale. Utilizza semplicemente l'associazione dei dati per associare la classe del modello a questo layout, come abbiamo definito nel layout xml sopra.
Ora possiamo finalmente arrivare alla parte davvero interessante: scrivere l'adattatore. Ho intenzione di saltare l'implementazione di base di Adapter
e mi concentrerò invece sulle parti che sono rilevanti per questa risposta.
Ma prima c'è una cosa di cui dobbiamo parlare: la SortedList
classe.
SortedList
Il SortedList
è uno strumento completamente stupefacente che fa parte della RecyclerView
biblioteca. Si occupa di notificare le Adapter
modifiche al set di dati e lo fa in modo molto efficiente. L'unica cosa che devi fare è specificare un ordine degli elementi. È necessario farlo implementando un compare()
metodo che confronta due elementi nel SortedList
proprio come un Comparator
. Ma invece di ordinare un List
viene usato per ordinare gli oggetti nel RecyclerView
!
Le SortedList
interagisce con il Adapter
tramite di una Callback
classe che è necessario implementare:
private final SortedList.Callback<ExampleModel> mCallback = new SortedList.Callback<ExampleModel>() {
@Override
public void onInserted(int position, int count) {
mAdapter.notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
mAdapter.notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
mAdapter.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
mAdapter.notifyItemRangeChanged(position, count);
}
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
}
Nei metodi nella parte superiore della richiamata come onMoved
, onInserted
ecc dovete chiamare l'equivalente metodo vostra notificare Adapter
. I tre metodi in basso compare
, areContentsTheSame
e areItemsTheSame
devi implementare in base al tipo di oggetti che vuoi visualizzare e in quale ordine questi oggetti dovrebbero apparire sullo schermo.
Esaminiamo questi metodi uno per uno:
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
Questo è il compare()
metodo di cui ho parlato prima. In questo esempio sto solo passando la chiamata a una Comparator
che confronta i due modelli. Se si desidera che gli elementi vengano visualizzati in ordine alfabetico sullo schermo. Questo comparatore potrebbe apparire così:
private static final Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = new Comparator<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return a.getText().compareTo(b.getText());
}
};
Ora diamo un'occhiata al prossimo metodo:
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
Lo scopo di questo metodo è determinare se il contenuto di un modello è cambiato. Lo SortedList
utilizza per determinare se è necessario invocare un evento di modifica, in altre parole se si RecyclerView
deve dissolvere la versione precedente e nuova. Se le tue classi di modelli hanno una corretta equals()
e hashCode()
implementazione, di solito puoi semplicemente implementarla come sopra. Se aggiungiamo un equals()
e hashCode()
implementazione per la ExampleModel
classe che dovrebbe essere simile a questa:
public class ExampleModel implements SortedListAdapter.ViewModel {
private final long mId;
private final String mText;
public ExampleModel(long id, String text) {
mId = id;
mText = text;
}
public long getId() {
return mId;
}
public String getText() {
return mText;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExampleModel model = (ExampleModel) o;
if (mId != model.mId) return false;
return mText != null ? mText.equals(model.mText) : model.mText == null;
}
@Override
public int hashCode() {
int result = (int) (mId ^ (mId >>> 32));
result = 31 * result + (mText != null ? mText.hashCode() : 0);
return result;
}
}
Nota a margine: la maggior parte degli IDE come Android Studio, IntelliJ ed Eclipse hanno funzionalità per generare equals()
e hashCode()
implementazioni per te con la semplice pressione di un pulsante! Quindi non è necessario implementarli da soli. Cerca su Internet come funziona nel tuo IDE!
Ora diamo un'occhiata all'ultimo metodo:
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
Il SortedList
utilizza questo metodo per controllare se due voci si riferiscono alla stessa cosa. In termini più semplici (senza spiegare come SortedList
funziona) questo viene usato per determinare se un oggetto è già contenuto List
nell'animazione e se è necessario riprodurre un'animazione di aggiunta, spostamento o modifica. Se i tuoi modelli hanno un ID, di solito confronteresti solo l'id in questo metodo. In caso contrario, devi trovare un altro modo per verificarlo, ma comunque finisci per implementarlo dipende dalla tua app specifica. Di solito è l'opzione più semplice per fornire un ID a tutti i modelli, che potrebbe ad esempio essere il campo chiave principale se si esegue una query sui dati da un database.
Con l' SortedList.Callback
implementazione corretta possiamo creare un'istanza di SortedList
:
final SortedList<ExampleModel> list = new SortedList<>(ExampleModel.class, mCallback);
Come primo parametro nel costruttore del SortedList
è necessario passare la classe dei tuoi modelli. L'altro parametro è proprio quello SortedList.Callback
sopra definito.
Ora mettiamoci al lavoro: se implementiamo il Adapter
con un SortedList
, dovrebbe assomigliare a questo:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
private final SortedList<ExampleModel> mSortedList = new SortedList<>(ExampleModel.class, new SortedList.Callback<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public void onInserted(int position, int count) {
notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
notifyItemRangeChanged(position, count);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
});
private final LayoutInflater mInflater;
private final Comparator<ExampleModel> mComparator;
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
mInflater = LayoutInflater.from(context);
mComparator = comparator;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
final ExampleModel model = mSortedList.get(position);
holder.bind(model);
}
@Override
public int getItemCount() {
return mSortedList.size();
}
}
L' Comparator
usato per ordinare l'oggetto viene passato attraverso il costruttore in modo che possiamo usare lo stesso Adapter
anche se si suppone che gli articoli vengano visualizzati in un ordine diverso.
Ora abbiamo quasi finito! Ma prima abbiamo bisogno di un modo per aggiungere o rimuovere elementi su Adapter
. A tale scopo possiamo aggiungere metodi ai Adapter
quali ci consentono di aggiungere e rimuovere elementi a SortedList
:
public void add(ExampleModel model) {
mSortedList.add(model);
}
public void remove(ExampleModel model) {
mSortedList.remove(model);
}
public void add(List<ExampleModel> models) {
mSortedList.addAll(models);
}
public void remove(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (ExampleModel model : models) {
mSortedList.remove(model);
}
mSortedList.endBatchedUpdates();
}
Non abbiamo bisogno di chiamare alcun metodo di notifica qui perché lo SortedList
fa già per tramite SortedList.Callback
! A parte ciò, l'implementazione di questi metodi è piuttosto semplice con un'eccezione: il metodo remove che rimuove un List
modello. Dal momento che SortedList
ha un solo metodo di rimozione che può rimuovere un singolo oggetto, dobbiamo scorrere l'elenco e rimuovere i modelli uno per uno. Chiamando beginBatchedUpdates()
all'inizio vengono SortedList
raggruppati tutti i cambiamenti che andremo a fare insieme e migliorano le prestazioni. Quando chiamiamo endBatchedUpdates()
il RecyclerView
viene notificato tutte le modifiche in una volta.
Inoltre, ciò che devi capire è che se aggiungi un oggetto a SortedList
ed è già SortedList
presente non verrà aggiunto di nuovo. Invece SortedList
usa il areContentsTheSame()
metodo per capire se l'oggetto è cambiato - e se ha l'elemento in RecyclerView
verrà aggiornato.
Comunque, quello che di solito preferisco è un metodo che mi consente di sostituire tutti gli elementi in RecyclerView
una volta. Rimuovi tutto ciò che non è presente List
e aggiungi tutti gli elementi mancanti da SortedList
:
public void replaceAll(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (int i = mSortedList.size() - 1; i >= 0; i--) {
final ExampleModel model = mSortedList.get(i);
if (!models.contains(model)) {
mSortedList.remove(model);
}
}
mSortedList.addAll(models);
mSortedList.endBatchedUpdates();
}
Questo metodo raggruppa nuovamente tutti gli aggiornamenti per aumentare le prestazioni. Il primo ciclo è al contrario poiché la rimozione di un elemento all'inizio comprometterebbe gli indici di tutti gli elementi che ne derivano e ciò può portare in alcuni casi a problemi come incoerenze dei dati. Dopodiché aggiungiamo semplicemente List
l' SortedList
uso addAll()
per aggiungere tutti gli elementi che non sono già presenti in SortedList
e - proprio come ho descritto sopra - aggiorniamo tutti gli elementi che sono già presenti in SortedList
ma che sono stati modificati.
E con ciò il Adapter
è completo. L'intero aspetto dovrebbe assomigliare a questo:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
private final SortedList<ExampleModel> mSortedList = new SortedList<>(ExampleModel.class, new SortedList.Callback<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public void onInserted(int position, int count) {
notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
notifyItemRangeChanged(position, count);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1 == item2;
}
});
private final Comparator<ExampleModel> mComparator;
private final LayoutInflater mInflater;
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
mInflater = LayoutInflater.from(context);
mComparator = comparator;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(mInflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
final ExampleModel model = mSortedList.get(position);
holder.bind(model);
}
public void add(ExampleModel model) {
mSortedList.add(model);
}
public void remove(ExampleModel model) {
mSortedList.remove(model);
}
public void add(List<ExampleModel> models) {
mSortedList.addAll(models);
}
public void remove(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (ExampleModel model : models) {
mSortedList.remove(model);
}
mSortedList.endBatchedUpdates();
}
public void replaceAll(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (int i = mSortedList.size() - 1; i >= 0; i--) {
final ExampleModel model = mSortedList.get(i);
if (!models.contains(model)) {
mSortedList.remove(model);
}
}
mSortedList.addAll(models);
mSortedList.endBatchedUpdates();
}
@Override
public int getItemCount() {
return mSortedList.size();
}
}
L'unica cosa che manca ora è implementare il filtro!
Implementazione della logica del filtro
Per implementare la logica del filtro dobbiamo prima definire uno List
di tutti i possibili modelli. Per questo esempio creo una List
delle ExampleModel
istanze da una serie di film:
private static final String[] MOVIES = new String[]{
...
};
private static final Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = new Comparator<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return a.getText().compareTo(b.getText());
}
};
private ExampleAdapter mAdapter;
private List<ExampleModel> mModels;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mAdapter = new ExampleAdapter(this, ALPHABETICAL_COMPARATOR);
mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
mBinding.recyclerView.setAdapter(mAdapter);
mModels = new ArrayList<>();
for (String movie : MOVIES) {
mModels.add(new ExampleModel(movie));
}
mAdapter.add(mModels);
}
Non sta succedendo nulla di speciale qui, abbiamo solo un'istanza di Adapter
e impostato su RecyclerView
. Successivamente, creiamo una serie List
di modelli dai nomi dei film nella MOVIES
matrice. Quindi aggiungiamo tutti i modelli a SortedList
.
Ora possiamo tornare a ciò onQueryTextChange()
che abbiamo definito in precedenza e iniziare a implementare la logica del filtro:
@Override
public boolean onQueryTextChange(String query) {
final List<ExampleModel> filteredModelList = filter(mModels, query);
mAdapter.replaceAll(filteredModelList);
mBinding.recyclerView.scrollToPosition(0);
return true;
}
Questo è di nuovo piuttosto semplice. Chiamiamo il metodo filter()
e passiamo in List
of ExampleModel
s così come nella stringa di query. Chiamiamo quindi replaceAll()
il Adapter
e passiamo al filtro List
restituito da filter()
. Dobbiamo anche chiamare scrollToPosition(0)
il RecyclerView
per garantire che l'utente possa sempre vedere tutti gli elementi durante la ricerca di qualcosa. In caso contrario, RecyclerView
potrebbero rimanere in una posizione di scorrimento verso il basso durante il filtraggio e successivamente nascondere alcuni elementi. Lo scorrimento verso l'alto assicura un'esperienza utente migliore durante la ricerca.
L'unica cosa che resta da fare ora è implementare filter()
se stesso:
private static List<ExampleModel> filter(List<ExampleModel> models, String query) {
final String lowerCaseQuery = query.toLowerCase();
final List<ExampleModel> filteredModelList = new ArrayList<>();
for (ExampleModel model : models) {
final String text = model.getText().toLowerCase();
if (text.contains(lowerCaseQuery)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
La prima cosa che facciamo qui è chiamare toLowerCase()
la stringa di query. Non vogliamo che la nostra funzione di ricerca sia sensibile al maiuscolo / minuscolo e chiamando toLowerCase()
tutte le stringhe che confrontiamo possiamo assicurarci di restituire gli stessi risultati indipendentemente dal caso. Quindi scorre solo attraverso tutti i modelli in cui List
siamo passati e verifica se la stringa di query è contenuta nel testo del modello. In tal caso, il modello viene aggiunto al filtro List
.
E questo è tutto! Il codice sopra verrà eseguito a livello di API 7 e superiore e a partire dal livello API 11 otterrai animazioni di oggetti gratis!
Mi rendo conto che questa è una descrizione molto dettagliata che probabilmente rende l'intera faccenda più complicata di quanto non sia in realtà, ma c'è un modo per generalizzare l'intero problema e rendere l'implementazione Adapter
basata su una SortedList
molto più semplice.
Generalizzare il problema e semplificare l'adattatore
In questa sezione non ho intenzione di entrare nei dettagli, in parte perché sto correndo contro il limite di caratteri per le risposte su Stack Overflow, ma anche perché la maggior parte è già spiegata sopra, ma per riassumere le modifiche: possiamo implementare una Adapter
classe base che si occupa già di gestire i SortedList
modelli oltre che vincolanti per le ViewHolder
istanze e fornisce un modo conveniente per implementare un Adapter
basato su a SortedList
. Per questo dobbiamo fare due cose:
- Dobbiamo creare
ViewModel
un'interfaccia che tutte le classi di modelli devono implementare
- Dobbiamo creare una
ViewHolder
sottoclasse che definisce un bind()
metodo che Adapter
può essere utilizzato per associare automaticamente i modelli.
Questo ci consente di concentrarci solo sul contenuto che dovrebbe essere visualizzato nel RecyclerView
semplicemente implementando i modelli e le relative ViewHolder
implementazioni. Usando questa classe base non dobbiamo preoccuparci degli intricati dettagli di Adapter
e suoi SortedList
.
SortedListAdapter
A causa del limite di caratteri per le risposte su StackOverflow non posso passare attraverso ogni fase dell'implementazione di questa classe di base o persino aggiungere qui il codice sorgente completo, ma puoi trovare il codice sorgente completo di questa classe base - l'ho chiamato SortedListAdapter
- in questo GitHub Gist .
Per semplificarti la vita, ho pubblicato una libreria su jCenter che contiene il SortedListAdapter
! Se vuoi usarlo, tutto ciò che devi fare è aggiungere questa dipendenza al file build.gradle della tua app:
compile 'com.github.wrdlbrnft:sorted-list-adapter:0.2.0.1'
Puoi trovare maggiori informazioni su questa biblioteca nella homepage della biblioteca .
Utilizzo di SortedListAdapter
Per usare il SortedListAdapter
dobbiamo fare due cambiamenti:
Cambia in ViewHolder
modo che si estenda SortedListAdapter.ViewHolder
. Il parametro type dovrebbe essere il modello che dovrebbe essere associato a questo ViewHolder
- in questo caso ExampleModel
. Devi associare i dati ai tuoi modelli performBind()
anziché a bind()
.
public class ExampleViewHolder extends SortedListAdapter.ViewHolder<ExampleModel> {
private final ItemExampleBinding mBinding;
public ExampleViewHolder(ItemExampleBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
@Override
protected void performBind(ExampleModel item) {
mBinding.setModel(item);
}
}
Assicurati che tutti i tuoi modelli implementino l' ViewModel
interfaccia:
public class ExampleModel implements SortedListAdapter.ViewModel {
...
}
Dopodiché non ci resta che aggiornare il ExampleAdapter
per estendere SortedListAdapter
e rimuovere tutto ciò di cui non abbiamo più bisogno. Il parametro type dovrebbe essere il tipo di modello con cui stai lavorando, in questo caso ExampleModel
. Ma se stai lavorando con diversi tipi di modelli, imposta il parametro type su ViewModel
.
public class ExampleAdapter extends SortedListAdapter<ExampleModel> {
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
super(context, ExampleModel.class, comparator);
}
@Override
protected ViewHolder<? extends ExampleModel> onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
protected boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
@Override
protected boolean areItemContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
}
Dopo di ciò abbiamo finito! Comunque un'ultima cosa da menzionare: The SortedListAdapter
non ha lo stesso add()
, remove()
o replaceAll()
metodi che il nostro originale ExampleAdapter
aveva. Utilizza un Editor
oggetto separato per modificare gli elementi nell'elenco a cui è possibile accedere tramite il edit()
metodo. Quindi, se si desidera rimuovere o aggiungere elementi che è necessario chiamare, edit()
aggiungere e rimuovere gli elementi in questa Editor
istanza e, una volta terminato, chiamare commit()
per applicare le modifiche a SortedList
:
mAdapter.edit()
.remove(modelToRemove)
.add(listOfModelsToAdd)
.commit();
Tutte le modifiche apportate in questo modo vengono raggruppate per aumentare le prestazioni. Il replaceAll()
metodo che abbiamo implementato nei capitoli sopra è presente anche su questo Editor
oggetto:
mAdapter.edit()
.replaceAll(mModels)
.commit();
Se si dimentica di chiamare, commit()
nessuna delle modifiche verrà applicata!