使用PagedList,这里没有数据库支持,但是内存中有一个数据列表(称为CachedDataList),可以由fetchMore()函数填充。

具有PositionalDataSourceDataSource.FactoryPagedList.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

09-05 10:27