使用RecyclerView适配器更新数据的最佳方法

时间:2015-05-05 12:54:41

标签: android listview android-recyclerview android-adapter

当我必须使用带有ListView的经典适配器时,我会更新ListView中的数据,如下所示:

myAdapter.swapArray(data);

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

我想知道RecyclerView的最佳做法是什么。因为在 RecyclerView 适配器中,您无法像 ListView 那样执行clearaddAll

所以我尝试使用notifyDataSetChanged,但它没有用。 然后我尝试在我的视图上使用swapAdapter:

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的情况下更改我的数据。

4 个答案:

答案 0 :(得分:102)

RecyclerView的适配器没有附带ListView适配器中提供的许多方法。但是您的交换可以非常简单地实现:

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

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

之间也有区别
list.clear();
list.add(data);

list = newList;

第一个是重用相同的列表对象。另一种是解除引用和引用列表。无法再访问的旧列表对象将被垃圾收集,但不是没有首先堆积堆内存。这与每次要交换数据时初始化新适配器相同。

答案 1 :(得分:21)

@ inmyth的回答是正确的,只需修改一下代码,即可处理空列表。

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

我正在使用Retrofit来获取列表,在Retrofit的onResponse()上使用,

adapter.swap(feedList);

答案 2 :(得分:10)

DiffUtil是更新您在android框架中可以找到的RecyclerView Adapter中的数据的最佳选择。 DiffUtil是一个实用程序类,可以计算两个列表之间的差异,并输出一个更新操作列表,将第一个列表转换为第二个列表。

大多数情况下,我们的列表完全更改,我们将新列表设置为RecyclerView Adapter。我们调用notifyDataSetChanged来更新适配器。 NotifyDataSetChanged成本很高。 DiffUtil类现在解决了这个问题。它完美地完成了它的工作!

答案 3 :(得分:4)

找到以下解决方案解决我的类似问题:

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

使用clear-command

mData.clear()

不是nessescary