订阅liveData后如何仅观察新更新的liveData

lan*_*nyf 6 android pagedlist observer-pattern kotlin android-livedata

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

拥有PositionalDataSourceDataSource.FactoryPagedList.BoundaryCallback,它在这里只是一个问题。

该流程是PositionalDataSource的loadInitial()开始时将被调用,以开始从中加载数据 CachedDataList,然后再调用loadRange()以继续从CachedDataList按页面大小加载数据 。

CachedDataList页面中的所有数据都被分页后,BoundaryCallback::onItemAtEndLoaded()将调用(如果开始时没有后备数据,则将BoundaryCallback::onZeroItemsLoaded()调用),

在那里,它将开始要求fetchMore将更多数据添加到中CachedDataList,并在将新数据添加到其中时,调用DataSource 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
Run Code Online (Sandbox Code Playgroud)

在这里,它观察observableCachedData的变化,如果有变化 onChanged(),则

class RefreshHandler(val observableCachedData: MutableLiveData<List<Data>>) : Observer<List<Data>> {
override fun onChanged(datalist: List<Data>?)
Run Code Online (Sandbox Code Playgroud)

将被调用,并在其中调用数据源的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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

kat*_*moi 1

您可以使用 SingleLiveEvent

单一现场活动