как наблюдать liveData только для нового обновления после подписки на liveData - PullRequest
0 голосов
/ 22 мая 2018

с использованием 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()
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

заставил его работать с проверкой списка отправленных данных в RefreshHandler(val observableCachedData: MutableLiveData<List<Data>>), аннулировать только, если в список добавлено больше.

(следует искать лучший способ определить, действительно ли увеличился список данных).

inner class RefreshHandler(val observableCachedData: MutableLiveData<List<Data>>) : Observer<List<Data>> {
    val oldData = observableCachedData.value
    override fun onChanged(datalist: List<Data>?) {

        if (datalist.size == oldData.size) {
             // is from previous cached data in the liveData
             return
        }

        observableCachedData.removeObserver(refreshHandler!!)
        val dataSource = dataSourceFactory.getPositionalDataSource()

        // to start a new PagedList and DataSource pair flow
        // and trigger the DataSource's loadInitial()
        dataSource.invalidate()
    }
}
0 голосов
/ 22 мая 2018

Вы можете использовать SingleLiveEvent

SingleLiveEvent

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...