使用回收视图适配器更新数据的最佳方式

当我必须使用带有 列表视图的经典适配器时,我会像下面这样更新 ListView 中的数据:

myAdapter.swapArray(data);


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

我想知道什么是 回收视图的最佳实践。因为在 回收视图适配器中,你不能像在 列表视图中那样做 clearaddAll

所以我用 notifyDataSetChanged试了试,但没用。 然后我尝试在我的视图中使用交换适配器:

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);

但是在最后一个解决方案中,我仍然需要创建适配器的一个新实例,我觉得这不是最好的解决方案。我应该能够只是改变我的数据没有一个新的 MyRecyclerAdapter

111747 次浏览

RecyclerView's Adapter doesn't come with many methods otherwise available in ListView's adapter. But your swap can be implemented quite simply as:

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


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

Also there is a difference between

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

and

list = newList;

The first is reusing the same list object. The other is dereferencing and referencing the list. The old list object which can no longer be reached will be garbage collected but not without first piling up heap memory. This would be the same as initializing new adapter everytime you want to swap data.

@inmyth's answer is correct, just modify the code a bit, to handle empty list.

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();
}

I am using Retrofit to fetch the list, on Retrofit's onResponse() use,

adapter.swap(feedList);

Found following solution working for my similar problem:

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();
}

Using the clear-command

mData.clear()

is not nessescary

DiffUtil can the best choice for updating the data in the RecyclerView Adapter which you can find in the android framework. DiffUtil is a utility class that can calculate the difference between two lists and output a list of update operations that converts the first list into the second one.

Most of the time our list changes completely and we set new list to RecyclerView Adapter. And we call notifyDataSetChanged to update adapter. NotifyDataSetChanged is costly. DiffUtil class solves that problem now. It does its job perfectly!