使用RecyclerView适配器更新数据的最佳方法
当我不得不使用一个经典的适配器与ListView ,我更新我的数据在这样的ListView:
myAdapter.swapArray(data); public swapArray(List<Data> data) { clear(); addAll(data); notifyDataSetChanged(); }
我想知道什么是RecyclerView的最佳做法。 因为在RecyclerView适配器中,您不能像ListView中那样执行clear
和addAll
。
所以我尝试了一个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);
但是通过这个最后的解决scheme,我仍然需要创build一个新的适配器实例,我觉得这不是最好的解决scheme。 我应该能够更改我的数据,而不需要新的MyRecyclerAdapter
。
RecyclerView的适配器没有提供许多方法,否则在ListView的适配器可用。 但是你的交换可以简单地实现为:
class MyRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { List<Data> data; ... public void swap(ArrayList<Data> datas) { if(datas == null || datas.size()==0) return; if (data != null && data.size()>0) 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);
DiffUtil可以更新您可以在Android框架中find的RecyclerView适配器中的数据的最佳select。 DiffUtil是一个实用工具类,可以计算两个列表之间的差异,并输出将第一个列表转换为第二个列表的更新操作列表。
大部分时间我们的列表完全改变,我们设置新的列表RecyclerView适配器。 我们调用notifyDataSetChanged来更新适配器。 NotifyDataSetChanged是昂贵的。 DiffUtil类现在解决了这个问题。 它完美地完成了它的工作!
find以下解决scheme为我的类似问题工作:
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()
是不是nessescary