Как наблюдать данные PagedList?

Я использую Paging Library и компоненты Android Architecture. Я просто хочу наблюдать pagedlist livedata и обновлять свой RecyclerView при изменении.

Я наблюдаю объекты isLoadingLiveData, isEmptyLiveData и errorLiveData, которые являются объектами MediatorLiveData, созданными в моей модели ViewModel и наблюдаемые в моем фрагменте. А также наблюдение resultLiveData, которое возвращает выбранный список Gist с удаленного.

В моей модели ViewModel я создал PagedList LiveData, и всякий раз, когда он менялся, я хотел обновить isLoadingLiveData, isEmptyLiveData, errorLiveData и PagedListAdapter . Поэтому я определил isLoadingLiveData, isEmptyLiveData, errorLiveData и resultLiveData как объекты MediatorLiveData. Я добавил resultLiveData в качестве источника этих объектов. Поэтому, когда resultLiveData изменился, будут вызваны эти методы onChanged. И resultLiveData зависит от userNameLiveData, поэтому при изменении userNameLiveData будет вызываться allGistsLiveData и будет извлекать данные. Например, когда пользователь прокручивает список, я устанавливаю userNameLiveData и снова выполняю сетевой вызов.

Моя модель просмотра:

private val userNameLiveData = MutableLiveData<String>() private var gists: LiveData<PagedList<Gist>>? = null val allGistsLiveData: LiveData<PagedList<Gist>> get() { if (null == gists) { gists = GistModel(NetManager(getApplication()), getApplication()).getYourGists(userNameLiveData.value!!).create(0, PagedList.Config.Builder() .setPageSize(PAGED_LIST_PAGE_SIZE) .setInitialLoadSizeHint(PAGED_LIST_PAGE_SIZE) .setEnablePlaceholders(PAGED_LIST_ENABLE_PLACEHOLDERS) .build()) } return gists!! } val resultLiveData = MediatorLiveData<LiveData<PagedList<Gist>>>().apply { this.addSource(userNameLiveData) { gists = null this.value = allGistsLiveData } } val isLoadingLiveData = MediatorLiveData<Boolean>().apply { this.addSource(resultLiveData) { this.value = false } } val isEmptyLiveData = MediatorLiveData<Boolean>().apply { this.addSource(resultLiveData) { this.value = false } } val errorLiveData = MediatorLiveData<Boolean>().apply { this.addSource(resultLiveData) { if (it == null) { this.value = true } } } fun setUserName(userName: String) { userNameLiveData.value = userName } 

и мой фрагмент:

 override fun onViewCreated(view: View?, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.isEmptyLiveData.observe(this@YourGistsFragment, Observer<Boolean> { isVisible -> emptyView.visibility = if (isVisible!!) View.VISIBLE else View.GONE }) viewModel.isLoadingLiveData.observe(this@YourGistsFragment, Observer<Boolean> { it?.let { swipeRefreshLayout.isRefreshing = it } }) viewModel.errorLiveData.observe(this@YourGistsFragment, Observer<Boolean> { it?.let { showSnackBar(context.getString(R.string.unknown_error)) } }) viewModel.setUserName("melomg") viewModel.resultLiveData.observe(this@YourGistsFragment, Observer { it -> gistAdapter.setList(it?.value) }) } override fun onRefresh() { viewModel.setUserName("melomg") } 

мой репозиторий:

 fun getYourGists(userName: String): LivePagedListProvider<Int, Gist> { return remoteDataSource.getYourGists(userName, GitHubApi.getGitHubService(context)) } 

мой remoteDataSource:

 fun getYourGists(username: String, dataProvider: GitHubService): LivePagedListProvider<Int, Gist> { return object : LivePagedListProvider<Int, Gist>() { override fun createDataSource(): GistTiledRemoteDataSource<Gist> = object : GistTiledRemoteDataSource<Gist>(username, dataProvider) { override fun convertToItems(items: ArrayList<Gist>?): ArrayList<Gist>? { return items } } } } 

Я попытался создать это решение из этого проекта . Но моя проблема – resultLiveData меняется, не дожидаясь ответа на сетевой вызов, и поэтому результат ответа игнорируется, а мой ui обновляется до того, как данные прибыли. Поскольку resultLiveData меняется перед запросом, и поэтому данных пока нет. Просто как я могу наблюдать pagedlist livingata?

Наконец, я нашел рабочее решение, но я не думаю, что это лучшее решение. Поэтому, если у вас есть идеи, пожалуйста, не стесняйтесь отвечать. Вот мое решение:

Я отказался от переноса данных PagedList с помощью MediatorLiveData . Я все еще оставляю все остальные данные в реальном времени ( isLoadingLiveData, isEmptyLiveData, errorLiveData ) как MediatorLiveData но добавил их источник, когда инициализировались мои gists PagedList LiveData. Вот код:

 private var gists: LiveData<PagedList<Gist>>? = null private val userNameLiveData = MutableLiveData<String>() val isLoadingLiveData = MediatorLiveData<Boolean>() val isEmptyLiveData = MediatorLiveData<Boolean>() val errorLiveData = MediatorLiveData<ErrorMessage>() val allGistsLiveData: LiveData<PagedList<Gist>> get() { if (gists == null) { gists = GistModel(NetManager(getApplication()), getApplication()).getYourGists(userNameLiveData.value!!).create(0, PagedList.Config.Builder() .setPageSize(Constants.PAGED_LIST_PAGE_SIZE) .setInitialLoadSizeHint(Constants.PAGED_LIST_PAGE_SIZE) .setEnablePlaceholders(Constants.PAGED_LIST_ENABLE_PLACEHOLDERS) .build()) isLoadingLiveData.addSource(gists) { isLoadingLiveData.value = false } isEmptyLiveData.addSource(gists) { if (it?.size == 0) { isEmptyLiveData.value = true } } errorLiveData.addSource(gists) { if (it == null) { errorLiveData.value = ErrorMessage(errorCode = ErrorCode.GENERAL_ERROR) } } } } return gists!! } fun setUserName(userName: String) { isLoadingLiveData.value = true userNameLiveData.value = userName gists = null allGistsLiveData }