Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Data class that is necessary for a UI to show a listing and interact w/ the rest of the system
- */
- data class Listing<T>(
- // the LiveData of paged lists for the UI to observe
- val pagedList: LiveData<PagedList<T>>,
- // represents the network request status to show to the user
- val networkState: LiveData<NetworkState>,
- // represents the refresh status to show to the user. Separate from networkState, this
- // value is importantly only when refresh is requested.
- val refreshState: LiveData<NetworkState>,
- // refreshes the whole data and fetches it from scratch.
- val refresh: () -> Unit,
- // retries any failed requests.
- val retry: () -> Unit)
- class DataSource(
- private val apiService: ApiService,
- private val retryExecutor: Executor,
- //You can pass all other extra params that you need here.
- ) : PageKeyedDataSource<Int, Deliverable>() {
- // keep a function reference for the retry event
- private var retry: (() -> Any)? = null
- /**
- * There is no sync on the state because paging will always call loadInitial first then wait
- * for it to return some success value before calling loadAfter.
- */
- val networkState = MutableLiveData<NetworkState>()
- val initialLoad = SingleLiveEvent<NetworkState>()
- fun retryAllFailed() {
- val prevRetry = retry
- retry = null
- prevRetry?.let {
- retryExecutor.execute {
- it.invoke()
- }
- }
- }
- override fun loadInitial(params: LoadInitialParams<Int>, callback: LoadInitialCallback<Int, Deliverable>) {
- Timber.d("Loading initial value")
- }
- override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, Deliverable>) {
- Timber.d("Load after called. Offset: ${params.key}, Page size: ${params.requestedLoadSize}")
- }
- override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, Deliverable>) {
- Timber.d("Load before called")
- //This is never used
- }
- }
- class DataSourceFactory(
- private val apiservice: ApiService,
- private val retryExecutor: Executor,
- //You can pass all other extra params that you need here.
- ) : DataSource.Factory<Int, Deliverable>() {
- val sourceLiveData = MutableLiveData<DataSource>()
- override fun create(): DataSource<Int, Deliverable> {
- val source = DataSource(//Pass all required params here.)
- sourceLiveData.postValue(source)
- return source
- }
- }
- //Then on the repository or any other place you are creating your data source
- fun history(//Pass params here): Listing<Deliverable> {
- val sourceFactory = DataSourceFactory(//Pass params)
- val config = PagedList.Config.Builder()
- .setPageSize(10)
- .build()
- val livePageList = LivePagedListBuilder(sourceFactory, config)
- .build()
- val refreshState = Transformations.switchMap(sourceFactory.sourceLiveData) {
- it.initialLoad
- }
- return Listing(
- pagedList = livePageList,
- networkState = Transformations.switchMap(sourceFactory.sourceLiveData) {
- it.networkState
- },
- retry = { sourceFactory.sourceLiveData.value?.retryAllFailed() },
- refresh = { sourceFactory.sourceLiveData.value?.invalidate() },
- refreshState = refreshState
- )
- }
- //The in viewModel, observe network state and trigger retries as follows
- private val repoResult = //create repo list from rrepository
- private val transports = Transformations.switchMap(repoResult) { it.pagedList }!!
- private val networkState = Transformations.switchMap(repoResult) { it.networkState }!!
- private val refreshState = Transformations.switchMap(repoResult) { it.refreshState }!!
- //call refresh and retry as follows
- fun refresh() {
- repoResult.value?.refresh?.invoke()
- }
- fun retry() {
- val listing = repoResult?.value
- listing?.retry?.invoke()
- }
Add Comment
Please, Sign In to add comment