PagedListAdapter перезагрузить данные без заполнителей
Я использую PagedListAdapter и должен перезагрузить данные, когда экран возобновляется.
В этом случае я не хочу очищать адаптер и показывать его пустым или заполнителей во время загрузки данных.
Я хочу показать предыдущие данные и просто обновить их с помощью различий, как только новые данные будут получены.
Но теперь, когда я делаю dataSource.invalidate()
он немедленно отправляет пустой список, который вызывает очистку адаптера и отображение заполнителей.
Теперь мой код выглядит так:
class PortfolioListDataSource(
private val viewModel: PortfolioViewModel,
private val tabType: PortfolioTabType
) : PageKeyedDataSource<Int, Investment>() {
override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Investment>) {
val offset = 0
viewModel.loadInvestments(tabType, offset, Consumer {
val nextKey = if (it.data.size < params.requestedLoadSize) null else it.data.size
callback.onResult(it.data, offset, it.total, null, nextKey)
})
}
override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Investment>) {
val offset = params.key
viewModel.loadInvestments(tabType, offset, Consumer {
val nextKey = offset + it.data.size
callback.onResult(it.data, nextKey)
})
}
override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Investment>) {
}
class Factory(
val viewModel: PortfolioViewModel,
private val tabType: PortfolioTabType
) : DataSource.Factory<Int, Investment>() {
val sourceLiveData = MutableLiveData<PortfolioListDataSource>()
override fun create() = PortfolioListDataSource(viewModel, tabType)
.also { sourceLiveData.postValue(it) }
}
}
Здесь я инициализирую
val pagedListConfig = PagedList.Config.Builder()
.setInitialLoadSizeHint(20)
.setPageSize(20)
.build()
ordersLiveData = LivePagedListBuilder(factory, pagedListConfig).build()
Здесь я заполняю адаптер
viewModel.ordersLiveData.observe(this, Observer {
adapter.submitList(it)
})
И освежая это
// TODO Here I want to fetch new data, but not invalidate current dataset while it is loading
factory.sourceLiveData.value?.invalidate()
Я понятия не имею, как правильно это сделать
0 ответов
Да, invalidate() очищает текущий набор данных. Итак, вы попадете в состояние загрузки / заполнителя. Также невозможно обновить определенную страницу. Допустим, вы находитесь на 5-й странице и хотите обновить данные на этой конкретной странице. Это также невозможно без вызова invalidate(), который очистит набор данных и перейдет в Recyclerview на первую страницу (вверху списка).
Единственный способ избавиться от всех этих проблем - ввести слой постоянства с Room.https://github.com/googlesamples/android-architecture-components/tree/master/PagingWithNetworkSample
В соответствии с документами здесь:https://developer.android.com/reference/androidx/paging/DataSource
Если у вас есть более детализированные сигналы обновления, такие как сетевой API, сигнализирующий об обновлении одного элемента в списке, рекомендуется загружать данные из сети в память. Затем представьте эти данные в PagedList через DataSource, который является оболочкой для моментального снимка в памяти. Каждый раз, когда копия в памяти изменяется, можно сделать недействительным предыдущий источник данных, и может быть создан новый, обертывающий новое состояние моментального снимка.
https://developer.android.com/topic/libraries/architecture/paging/data
Создавая наблюдаемые объекты PagedList, подумайте, как работают обновления содержимого. Если вы загружаете данные непосредственно из базы данных Room, обновления автоматически передаются в пользовательский интерфейс вашего приложения.
В вашем случае вы всегда можете загрузить данные из БД при возобновлении работы экрана, пока не будут получены данные из вашего API.