Оптимизация обновления RecyclerView

164
01 февраля 2020, 13:10

Все мы знаем хрестоматийный пример работы с RecyclerView:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list);
// items - список объектов для отображения.
DataAdapter adapter = new DataAdapter(this, items);
recyclerView.setAdapter(adapter);

Из этого примера вытекает простой способ обновления RecyclerView - передать в адаптер новый список items. Однако это не всегда приемлемо, потому, что приводит к полной перерисовке RecyclerView, что вызывает тормоза в GUI при большом количестве объектов.

Есть ли возможность обновлять RecyclerView не передавая новый items целиком, а добавляя новые объекты к уже имеющимся, чтобы RecyclerView отрисовывал только недостающую часть?

Answer 1

Есть класс DiffUtil. Он сравнит два набора данных: старый и новый, выяснит, какие произошли изменения, и с помощью notify методов оптимально обновит адаптер.

От нас требуется только наследовать класс DiffUtil.Callback и реализовать несколько его абстрактных методов.

public class ListDiffUtils extends DiffUtil.Callback {
    private final List<Data> oldData;
    private final List<Data> newData;
    StepsListDiffUtils(@NonNull List<Data> oldData, @NonNull List<Data> newData) {
        this.oldData = oldData;
        this.newData = newData;
    }
    @Override
    public int getOldListSize() {
        return oldData.size();
    }
    @Override
    public int getNewListSize() {
        return newData.size();
    }
    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldData.get(oldItemPosition).getDate() == newData.get(newItemPosition).getDate();
}
    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        return oldData.get(oldItemPosition).equals(newData.get(newItemPosition));
    }
}

Используем наш созданный DiffUtilCallback

public class Adapter extends RecyclerView.Adapter<Adapter.StepsViewHolder> {
    private List<Data> dataList = new ArrayList<>();
    //some code
    public void updateAdapter(List<Data> data) {
        DiffUtil.DiffResult result = DiffUtil.calculateDiff(new ListDiffUtils(dataList, data));
        dataList.clear();
        dataList.addAll(data);
        result.dispatchUpdatesTo(this);
    }
}

https://startandroid.ru/ru/blog/504-primer-ispolzovanija-android-diffutil.html здесь можно рассмотреть подробный пример.

READ ALSO
2048 Game //Java

2048 Game //Java

Нужно поставить двойку в случайний пустой JLabel по нажатию на кнопку "Start"

159
Локализация Java-класса в Android

Локализация Java-класса в Android

Знаю как локализовать ресурсы приложения (папку res)

161
Константа static + final, или только final?

Константа static + final, или только final?

Чтобы создать константу в Java, нужно пометить переменную сразу двумя модификаторами: static и finalПрочитал это в книге, а если просто переменную...

163