ListAdapter submitList() - Как перейти к началу

У меня проблема с моим RecyclerView и ListAdapter.

Через API я получаю элементы в возрастающем порядке от старых к новым.

Затем мой список обновляется путем вызова метода submitList (items).

Однако, поскольку все является асинхронным, после получения первого элемента RecyclerView остается на позиции первого полученного и отображенного элемента. Поскольку в классе ListAdapter нет обратного вызова при завершении метода submitList(), я не могу найти способ прокрутки после обновления одного из новых элементов, который был добавлен.

Есть ли способ перехватить, когда ListAdapter был обновлен?

Ответ 1

Не относится к ListAdapter, но, тем не менее, он должен работать:

Просто используйте adapter.registerAdapterDataObserver(RecyclerView.AdapterDataObserver) и переопределите соответствующий метод onItemXXX, чтобы ваш RecyclerView прокрутился до любой позиции.

В качестве примера:

    adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            (recycler_view.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(positionStart, 0)
        }
    })

Ответ 2

метод для переопределения называется:

public void onCurrentListChanged(List<T> previousList, List<T> currentList)

поскольку документация гласит:

Вызывается при обновлении текущего List.


встроенная документация ListAdapter гласит:

Этот класс является удобной оболочкой для AsyncListDiffer которая реализует общее поведение адаптера по умолчанию для доступа к элементам и их подсчета.

и позже это читает:

Опытные пользователи, которые хотят больше контролировать поведение адаптера или предоставить конкретный базовый класс, должны обратиться к AsyncListDiffer, который обеспечивает настраиваемое сопоставление от событий diff до позиций адаптера.

это означает, что вам нужно расширить обычный RecyclerView.Adapter сочетании с пользовательской реализацией AsyncListDiffer; а не ListAdapter (который является просто удобной оболочкой, с заявленной базовой функциональностью).

Вы можете использовать класс ListAdapter в качестве шаблона для этого (не расширять его, это ключ), но результирующий класс может быть расширен и использован повторно. иначе нет никакой возможности получить контроль над желаемым обратным вызовом.