Лучший способ обновления данных с помощью адаптера RecyclerView

Когда я должен использовать классический адаптер с ListView , я обновляю свои данные в ListView следующим образом:

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

Я хотел бы знать, что лучше всего подходит для RecyclerView . Поскольку в адаптере RecyclerView вы не можете делать clear и addAll как в ListView .

Поэтому я попробовал только с 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 не поставляется со многими другими способами, доступными в адаптере 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 для извлечения списка, использования onResponse () Retrofit,

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

Использование команды clear

 mData.clear() 

Не является обязательным

DiffUtil – лучший выбор для обновления данных в адаптере RecyclerView, который вы можете найти в инфраструктуре Android. DiffUtil – это класс утилиты, который может вычислять разницу между двумя списками и выводить список операций обновления, который преобразует первый список во второй.

В большинстве случаев наш список полностью меняется, и мы устанавливаем новый список для RecyclerView Adapter. И мы вызываем notifyDataSetChanged для обновления адаптера. NotifyDataSetChanged является дорогостоящим. Класс DiffUtil теперь решает эту проблему. Он отлично работает!