Как восстановить позицию прокрутки recyclerview при использовании PagingDataAdapter?

У меня есть приложение, которое извлекает список 158 элементов из API, сохраняет его в Room и отображает его пользователю. RoomDB - это источник правды.

Это код моей модели ViewModel, который получает результат из базы данных:

private val pagingConfig =
    PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 300)

fun getList(filters: Filters): Flow<PagingData<Character>> {
    return Pager(pagingConfig) {
        repository.getCharacters(filters)
    }.flow.map {
        it.asDomainModel()
    }
}

Это код моего фрагмента, который заполняет адаптер:

private fun fetchData(filters: Filters) {
    lifecycleScope.launch {
        charactersViewModel.getList(filters).collectLatest { pagedList ->
            characterAdapter.submitData(pagedList)
        }
    }
}

Текущее поведение:

  • Когда изменение конфигурации происходит после моего 60-го элемента, позиция прокрутки теряется, я обнаружил, что увеличение pageSize в моем pagingConfig с 20 до 55, устраняет эту проблему.

Что я уже пробовал:

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

characterAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY

Чего я ожидаю достичь:

Уметь прокручивать список до конца и вносить изменения в конфигурацию без потери позиции прокрутки без необходимости увеличивать мой pageSize по мере увеличения списка

https://github.com/doilio/DC-Characters


person Doilio Matsinhe    schedule 18.07.2020    source источник


Ответы (2)


Вы ищете метод PagingSource.getRefreshKey(). Ему дано предыдущее состояние, PagingState, в котором есть поле PagingState.anchorPosition, индекс, к которому был осуществлен последний доступ (включая заполнители).

https://developer.android.com/topic/libraries/architecture/paging/v3-network-db#refresh-in-place.

РЕДАКТИРОВАТЬ: теперь я вижу, что вы используете реализацию Room. На самом деле было несколько ошибок, связанных с Remote REFRESH и его реализацией getRefreshKey, которые должны быть устранены в следующем выпуске (alpha07). См. https://issuetracker.google.com/issues/167260236.

person dlam    schedule 18.07.2020
comment
Поскольку автор использует Room, мне интересно, работает ли PagingSource, созданный из Room, должным образом? (Хотя в документе говорится, что реализация PagingSource обрабатывает это за вас) - person shoheikawano; 27.09.2020
comment
Ах, я не уловил, что они сказали, что в первом предложении используется место :) В alpha07 есть несколько исправлений ошибок, которые должны решить эту проблему. - person dlam; 28.09.2020
comment
В alpha07 есть несколько исправлений ошибок, которые должны решить эту проблему. Звучит здорово!! С нетерпением жду этого :) - person shoheikawano; 29.09.2020

Была такая же проблема. В моей ситуации я изменил в PagingConfig enablePlaceholder на true и установил для initialLoadSize значение pageSize (например, pageSize = 10, initialLoadSize = 20).

person Fox    schedule 30.08.2020