Can't get data from data source factory when using Paging library in android

Viewed 56

I already did all the competent of the paging library tried to send all data to the UI following this artricle but no luck on getting the data here is my code

When I debugged I found the following: when it's loading the network state and pagedUserList get notified for the first time and when the request DONE only the network state get notified and the list doesn't get notified with the list itself and I don't know why? any clue?

MainActivity

    private fun initAdapter() {
    newsListAdapter = NewsListAdapter { mainViewModel.retry() }
    binder.rvUsers.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
    binder.rvUsers.adapter = newsListAdapter
    mainViewModel.getPagedList().observe(this, Observer {
        newsListAdapter.submitList(it)
    })
}

private fun initState() {
    binder.txtError.setOnClickListener { mainViewModel.retry() }
    mainViewModel.getState().observe(this, Observer { state ->
        binder.progressBar.visibility =
            if (mainViewModel.listIsEmpty() && state == State.LOADING) View.VISIBLE else View.GONE
        binder.txtError.visibility =
            if (mainViewModel.listIsEmpty() && state == State.ERROR) View.VISIBLE else View.GONE
        if (!mainViewModel.listIsEmpty()) {
            newsListAdapter.setState(state ?: State.DONE)
        }
    })
}

ViewModel

  private var pagedUserList: LiveData<PagedList<User>>
private val compositeDisposable = CompositeDisposable()
private val pageSize = 10
private val usersDataSourceFactory: UsersDataSourceFactory

init {

    usersDataSourceFactory = UsersDataSourceFactory(usersService, compositeDisposable)
    val config = PagedList.Config.Builder()
        .setPageSize(pageSize)
        .setInitialLoadSizeHint(pageSize * 3)
        .setEnablePlaceholders(false)
        .build()
    pagedUserList = LivePagedListBuilder<Int, User>(usersDataSourceFactory, config)
        .build();

}

fun getState(): LiveData<State> = Transformations.switchMap<UsersDataSource,
        State>(usersDataSourceFactory.getUserLiveData(), UsersDataSource::state)

fun retry() {
    usersDataSourceFactory.getUserLiveData().value?.retry()
}

fun listIsEmpty(): Boolean {
    return pagedUserList.value?.isEmpty() ?: true
}
fun getPagedList(): LiveData<PagedList<User>> {
    return pagedUserList
}

DataSourceFactory

class UsersDataSourceFactory(
private val usersService: UsersService,
private val compositeDisposable: CompositeDisposable
) : DataSource.Factory<Int, User>() {

  private val usersDataSourceLiveData = MutableLiveData<UsersDataSource>()

override fun create(): DataSource<Int, User> {
    val usersDataSource = UsersDataSource(usersService, compositeDisposable)

    usersDataSourceLiveData.postValue(usersDataSource)

    return usersDataSource
}

fun getUserLiveData() = usersDataSourceLiveData
}

DataSource

 class UsersDataSource(
  private val usersService: UsersService,
  private val compositeDisposable: CompositeDisposable
 ) : PageKeyedDataSource<Int, User>() {


var state: MutableLiveData<State> = MutableLiveData()
private var retryCompletable: Completable? = null

override fun loadInitial(
    params: LoadInitialParams<Int>,
    callback: LoadInitialCallback<Int, User>
) {

    updateState(State.LOADING)

    compositeDisposable.add(
        usersService.getUsers(0, 20)
            .subscribe({ response: List<User> ->

                updateState(State.DONE)
                val nextPageKey = response[response.size - 1].id
                callback.onResult(
                    response, null, nextPageKey
                )
            }, { t: Throwable? ->
                updateState(State.ERROR)
                setRetry(Action { loadInitial(params, callback) })

            })
    )
}

override fun loadAfter(params: LoadParams<Int>, callback: LoadCallback<Int, User>) {
    updateState(State.LOADING)

    compositeDisposable.add(
        usersService.getUsers(params.key + 1, 20)
            .subscribe({ response: List<User> ->

                updateState(State.DONE)
                if (!response.isEmpty()) {
                    val nextPageKey = response[response.size - 1].id
                    callback.onResult(response, nextPageKey)
                }else {
                    updateState(State.ERROR)
                    setRetry(Action { loadAfter(params, callback) })
                }

            }, { t: Throwable? ->
                updateState(State.ERROR)
                setRetry(Action { loadAfter(params, callback) })

            })
    )
}

override fun loadBefore(params: LoadParams<Int>, callback: LoadCallback<Int, User>) {
}


private fun updateState(state: State) {
    this.state.postValue(state)
}

fun retry() {
    if (retryCompletable != null) {
        compositeDisposable.add(
            retryCompletable!!
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe()
        )
    }
}

private fun setRetry(action: Action?) {
    retryCompletable = if (action == null) null else Completable.fromAction(action)
}
}

enum class State {
   DONE, LOADING, ERROR
}
0 Answers
Related