с использованием PagedList, и здесь у него нет базы данных назад, но есть список данных (назовите его CachedDataList
) в памяти, который может быть заполнен функцией fetchMore()
.
Наличие PositionalDataSource
, DataSource.Factory
и PagedList.BoundaryCallback
, это работает, но здесь есть одна проблема.
Поток loadInitial()
для PositionalDataSource будет вызываться в начале, чтобы начать загрузку данных из CachedDataList
, и вызвать loadRange()
после этого, чтобы продолжить загрузку данных из CachedDataList
по размеру страницы.
Когда все данные из CachedDataList
выгружаются, вызывается BoundaryCallback::onItemAtEndLoaded()
(если назатем начинается BoundaryCallback::onZeroItemsLoaded()
),
Там он начнет запрашивать fetchMore для добавления дополнительных данных в CachedDataList
, а когда к нему добавляются новые данные, вызывается invalidate()
источника данныхчтобы перезапустить новую пару PagedList и DataSource и снова начать с loadInitial()
PositionalDataSource.
Это делается здесь
observableCachedData.observe(owner, refreshHandler!!)
//??? TODO: how to only listen to newly posted data after
//starting the observe?
//DOC: 'If LiveData already has data set, it will be delivered to the observer.'
// fetchMore
val didFetch = dataRequester.fetchMore() //asyc call
, оно наблюдает за изменением observableCachedData, и если есть изменениетогда onChanged()
из
class RefreshHandler(val observableCachedData: MutableLiveData<List<Data>>) : Observer<List<Data>> {
override fun onChanged(datalist: List<Data>?)
и будет вызываться, чтобы вызвать invalidate ()
источника данных, но подписка на observableCachedData.observe()
вызывает refreshHandler
, вызываемую немедленно (этокак указано в DOC), это поведение здесь нежелательно, поскольку мы хотим, чтобы обработчик вызывался при добавлении новых данных к CachedDataList
.
, то есть CachedDataList
имел 30 данных, когдаfetchMore () к нему будут добавлены еще 30 данных, ставших 60. Но этот onChange()
вызывается с данными, которые все еще на 30 (добавление еще не пришло).
Есть ли способ подписатьсяк действительным данным, но получать уведомление об обновлении, которое произошло после того, как оно было подписано на них?
class DataBoundaryCallback(
private val owner: LifecycleOwner,
private val dataRequester: FetchMoreRequester,
private val dataSourceFactory: DataSourceFactory?
) : PagedList.BoundaryCallback<IData>() {
private var hasRequestInProgress = false
override fun onZeroItemsLoaded() {
requestAndSaveData()
}
override fun onItemAtEndLoaded(itemAtEnd: IData) {
requestAndSaveData()
}
private fun requestAndSaveData() {
if (hasRequestInProgress) return
hasRequestInProgress = true
// ask dataRequester to fetchMore
// setup observer
val cachedDataList = dataRequester.getCachedLiveData()
val observableCachedData = cachedDataList.getLiveData()
refreshHandler = RefreshHandler(observableCachedData)
observableCachedData.observe(owner, refreshHandler!!) //??? TODO: how to only listen to newly posted data after starting the observe? DOC: 'If LiveData already has data set, it will be delivered to the observer.'
// fetchMore
val didFetch = dataRequester.fetchMore()
if (!didFetch) { //not stated fetch
hasRequestInProgress = false
observableCachedData.removeObserver(refreshHandler!!)
}
}
var refreshHandler : RefreshHandler? = null
inner class RefreshHandler(val observableCachedData: MutableLiveData<List<Data>>) : Observer<List<Data>> {
override fun onChanged(datalist: List<Data>?) {
observableCachedData.removeObserver(refreshHandler!!)
val dataSource = dataSourceFactory.getPositionalDataSource()
// to start a new PagedList and DataSource pair flow
// and trigger the DataSource's loadInitial()
dataSource.invalidate()
}
}
}