Я использую Paging 3 с RemoteMediator, который показывает кэшированные данные при получении новых данных из сети. Когда я обновляю свой PagingDataAdapter
(вызывая на нем refresh()
), я хочу, чтобы мой RecyclerView прокручивался вверх после завершения обновления. В codelabs они пытаются справиться с этим с помощью loadStateFlow
следующим образом:
lifecycleScope.launch {
adapter.loadStateFlow
// Only emit when REFRESH LoadState for RemoteMediator changes.
.distinctUntilChangedBy { it.refresh }
// Only react to cases where Remote REFRESH completes i.e., NotLoading.
.filter { it.refresh is LoadState.NotLoading }
.collect { binding.list.scrollToPosition(0) }
}
Это действительно прокручивается вверх, но до завершения работы DiffUtil. Это означает, что если действительно новые данные вставлены вверху, RecyclerView не будет прокручиваться полностью вверх.
Я знаю, что у адаптеров RecyclerView есть обратный вызов AdapterDataObserver
, с помощью которого мы можем получить уведомление, когда DiffUtil закончит различать. Но это вызовет всевозможные состояния гонки с PREPEND
и APPEND
состояниями загрузки адаптера, которые также вызывают запуск DiffUtil (но здесь мы не хотим прокручивать вверх).
Одно из решений, которое могло бы работать, - передать PagingData.empty()
в PagingDataAdapter
и повторно запустить тот же запрос (простой вызов refresh
не сработает, потому что PagingData
теперь пуст и обновлять нечего), но я бы предпочел, чтобы мои старые данные были видны до тех пор, пока Я знаю, что обновление действительно прошло.