使用PagedList,这里没有数据库支持,但是内存中有一个数据列表(称为CachedDataList
),可以由fetchMore()
函数填充。
具有PositionalDataSource
,DataSource.Factory
和PagedList.BoundaryCallback
,它可以工作,但这里有一个问题。
该流程是PositionalDataSource的loadInitial()
会在开始时被调用,以开始从CachedDataList
加载数据,然后调用loadRange()
以继续按页面大小从CachedDataList
加载数据。
当CachedDataList
中的所有数据都被分页时,BoundaryCallback::onItemAtEndLoaded()
将被调用(如果开始时没有后备数据,则BoundaryCallback::onZeroItemsLoaded()
被调用),
在那里,它将开始要求fetchMore将更多数据添加到CachedDataList
中,并在将新数据添加到invalidate()
中时,调用DataSource的loadInitial()
以重新启动新的PagedList和DataSource对,并再次从PositionalDataSource的onChanged()
开始。
它是由
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的变化,如果有变化,则观察到的
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()
}
}
}
最佳答案
您可以使用SingleLiveEvent
SingleLiveEvent