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

Best way to update data with a RecyclerView adapter

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

myAdapter.swapArray(data);

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

我想知道 RecyclerView 的最佳做法是什么。因为在 RecyclerView 适配器中你不能像在 ListView.[=18= 中那样做 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.

的情况下更改我的数据

RecyclerView 的 Adapter 没有附带 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;

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

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

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

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

使用清除命令

mData.clear()

不可怕

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

大多数时候我们的列表会完全改变,我们将新列表设置为 RecyclerView Adapter。我们调用 notifyDataSetChanged 来更新适配器。 NotifyDataSetChanged 代价高昂。 DiffUtil class 现在解决了这个问题。它完美地完成了它的工作!