Лучший способ обновления данных с помощью адаптера 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
.
Ответы
Ответ 1
Адаптер 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;
Первый - это повторное использование одного и того же объекта списка. Другой разыменование и ссылки на список. Старый объект списка, который больше не может быть достигнут, будет собираться мусором, но не без предварительного накопления кучи памяти. Это будет то же самое, что и инициализация нового адаптера каждый раз, когда вы хотите поменять местами данные.
Ответ 2
@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);
Ответ 3
DiffUtil может быть лучшим выбором для обновления данных в адаптере RecyclerView, который вы можете найти в платформе Android. DiffUtil - это служебный класс, который может вычислить разницу между двумя списками и вывести список операций обновления, которые преобразуют первый список во второй.
Большую часть времени наш список полностью меняется, и мы устанавливаем новый список в RecyclerView Adapter. И мы вызываем notifyDataSetChanged для обновления адаптера. NotifyDataSetChanged является дорогостоящим. Класс DiffUtil теперь решает эту проблему. Он отлично выполняет свою работу!
Ответ 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()
не является обязательным