it-swarm.com.de

Beste Möglichkeit, Daten mit einem RecyclerView-Adapter zu aktualisieren

Wenn ich einen klassischen Adapter mit einem ListView verwenden muss, aktualisiere ich meine Daten in der ListView folgendermaßen:

myAdapter.swapArray(data);

public swapArray(List<Data> data) {
  clear();
  addAll(data);
  notifyDataSetChanged();
}

Ich würde gerne wissen, was die beste Vorgehensweise für ein RecyclerView ist. Denn in einem RecyclerView Adapter können Sie keine clear und addAll wie in ListView .

Also habe ich es nur mit einem notifyDataSetChanged versucht, aber es hat nicht funktioniert. Dann habe ich mit einem swapAdapter aus meiner Sicht versucht:

List<Data> data = newData;

MyRecyclerAdapter adapter = new MyRecyclerAdapter(data);

// swapAdapter on my recyclerView (instead of a .setAdapter like with a classic listView).
recyclerViewList.swapAdapter(adapter, false);

Aber mit dieser letzten Lösung muss ich immer noch eine neue Instanz meines Adapters erstellen, und ich bin der Meinung, dass dies nicht die beste Lösung ist. Ich sollte nur in der Lage sein, meine Daten ohne ein neues MyRecyclerAdapter zu ändern.

71
AlexDG

Der RecyclerView-Adapter enthält nicht viele Methoden, die sonst im ListView-Adapter verfügbar sind. Aber Ihr Swap kann ganz einfach implementiert werden als:

class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
   List<Data> data;
   ...

    public void swap(ArrayList<Data> datas)
    {
        data.clear();
        data.addAll(datas);
        notifyDataSetChanged();     
    }
}

Es gibt auch einen Unterschied zwischen

list.clear();
list.add(data);

und

list = newList;

Das erste ist die Wiederverwendung des gleichen Listenobjekts. Das andere ist die Dereferenzierung und Referenzierung der Liste. Das alte Listenobjekt, das nicht mehr erreicht werden kann, wird müllsammelbar sein, jedoch nicht ohne vorher Heapspeicher zu stapeln. Dies entspricht dem Initialisieren eines neuen Adapters, wenn Sie Daten austauschen möchten.

105
inmyth

Die Antwort von @ inmyth ist richtig, ändern Sie einfach den Code ein wenig, um mit leeren Listen umzugehen.

public class NewsAdapter extends RecyclerView.Adapter<...> {    
    ...
    private static List mFeedsList;
    ...    
    public void swap(List list){
            if (mFeedsList != null) {
                mFeedsList.clear();
                mFeedsList.addAll(list);
            }
            else {
                mFeedsList = list;
            }
            notifyDataSetChanged();
    }

Ich benutze Retrofit, um die Liste abzurufen, wenn Retrofit onResponse () verwendet,

adapter.swap(feedList);
21
Akshay Goyal

DiffUtil ist die beste Wahl für die Aktualisierung der Daten im RecyclerView Adapter, die Sie im Android Framework) finden. DiffUtil ist eine Utility-Klasse, mit der die Differenz zwischen zwei berechnet werden kann listet auf und gibt eine Liste von Aktualisierungsvorgängen aus, die die erste Liste in die zweite konvertiert.

Meistens ändert sich unsere Liste vollständig und wir setzen eine neue Liste auf RecyclerView Adapter. Und wir rufen notifyDataSetChanged auf, um den Adapter zu aktualisieren. NotifyDataSetChanged ist teuer. Die DiffUtil-Klasse löst dieses Problem jetzt. Es macht seinen Job perfekt!

11
Ngima Sherpa

Folgende Lösung für mein ähnliches Problem gefunden:

private ExtendedHashMap mData = new ExtendedHashMap();
private  String[] mKeys;

public void setNewData(ExtendedHashMap data) {
    mData.putAll(data);
    mKeys = data.keySet().toArray(new String[data.size()]);
    notifyDataSetChanged();
}

Mit dem clear-Befehl

mData.clear()

ist nicht notwendig

4
termigrator