Forcing Paging Library DataSource refresh

14.5k views Asked by At

In my ViewModel, I load data using

private val pagingConfig = PagedList.Config.Builder()
    .setEnablePlaceholders(false)
    .setInitialLoadSizeHint(INITIAL_LOAD_SIZE_HINT)
    .setPageSize(PAGE_SIZE)
    .build()

val notificationList = LivePagedListBuilder<Long, Notification>(dataSourceFactory, pagingConfig).build()

Which works fine. However, when my data changes, LiveData<PagedList<Notification>> does not get notified. Is there anything I can do to trigger LiveData refresh (the ViewModel knows when the change occurs).

2

There are 2 answers

3
Denysole On

You can trigger data update using invalidate() method from the DataSource.

When using the Paging Library, it's up to the data layer to notify the other layers of your app when a table or row has become stale. To do so, call invalidate() from the DataSource class that you've chosen for your app.

More information: Notify when data is invalid

3
Isaias Carrera On

According to official documentation: https://developer.android.com/topic/libraries/architecture/paging/data#notify-data-invalid

You have to call dataSourceLiveData.value?.invalidate()

I call it from my view like this:

OnRefresh: View implements SwipeRefreshLayout.OnRefreshListener

override fun onRefresh() {
    brewerViewModel.retry()
}

In define the method refresh in my view model:

fun refresh() {
    brewerDataSourceFactory.refresh()
}

In my case i'm using retrofit to fetch data from server

ItemResponse is the object which i'm getting from server (Retrofit)

class DataSourceFactory : DataSource.Factory<Int, ItemResponse>() {

    lateinit var dataSource: DataSource
    var dataSourceLiveData: MutableLiveData<DataSource> =
        MutableLiveData<DataSource>()

    override fun create(): DataSource<Int, ItemResponse> {

        dataSource = DataSource()
        dataSourceLiveData.postValue(dataSource)
        return dataSource

    }

    fun refresh() {
        dataSourceLiveData.value?.invalidate()
    }
}

In my DataSource is defined like following:

class DataSource : PageKeyedDataSource<Int, ItemResponse>

I hope it helps!