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

Ale*_*xDG 73 android listview android-adapter android-recyclerview

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

myAdapter.swapArray(data);

public swapArray(List<Data> data) {
  clear();
  addAll(data);
  notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)

我想知道RecyclerView的最佳实践是什么.因为在RecyclerView适配器,你不能做clear,并addAllListView控件.

所以我尝试了一下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);
Run Code Online (Sandbox Code Playgroud)

但是使用这个最后的解决方案,我仍然需要创建我的适配器的新实例,我觉得它不是最好的解决方案.我应该能够在没有新的情况下更改我的数据MyRecyclerAdapter.

inm*_*yth 108

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

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

    public void swap(ArrayList<Data> datas)
    {
        data.clear();
        data.addAll(datas);
        notifyDataSetChanged();     
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个区别

list.clear();
list.add(data);
Run Code Online (Sandbox Code Playgroud)

list = newList;
Run Code Online (Sandbox Code Playgroud)

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


Aks*_*yal 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();
    }
Run Code Online (Sandbox Code Playgroud)

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

adapter.swap(feedList);
Run Code Online (Sandbox Code Playgroud)


小智 12

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

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


ter*_*tor 5

发现以下解决方案适用于我的类似问题:

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();
}
Run Code Online (Sandbox Code Playgroud)

使用清除命令

mData.clear()
Run Code Online (Sandbox Code Playgroud)

不是必需的