¿Cómo observar los datos de PagedList?

Estoy usando Paging Library y Android Architecture Components. Simplemente quiero observar livedata de pagedlist y actualizar mi RecyclerView cuando hay un cambio.

Estoy observando objects isLoadingLiveData, isEmptyLiveData y errorLiveData que son objects MediatorLiveData creados en mi ViewModel y observados en mi fragment. Y también observando resultLiveData que devuelve la list Gist captada desde el control remoto.

En mi ViewModel, creé un PagedList LiveData y cada vez que cambian los datos, quería actualizar isLoadingLiveData, isEmptyLiveData, errorLiveData y PagedListAdapter . Por lo tanto, definí isLoadingLiveData, isEmptyLiveData, errorLiveData y resultLiveData como objects MediatorLiveData. Agregué resultLiveData como fuente de estos objects. Entonces cuando resultLiveData ha cambiado, se invocarán los methods onChanged de estos objects. Y resultLiveData depende de userNameLiveData, por lo que cuando userNameLiveData ha cambiado, se llamará a allGistsLiveData y obtendrá los datos. Por ejemplo, cuando el usuario desliza la list, estoy configurando userNameLiveData y haciendo una llamada de networking nuevamente.

Mi ViewModel:

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 } 

y mi fragment:

 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") } 

mi repository

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

mi 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 } } } } 

Traté de crear esta solución a partir de este proyecto . Pero mi problema es resultLiveData ha estado cambiando sin esperar la respuesta de llamada de networking y, por lo tanto, el resultado de la respuesta se ha ignorado y mi interfaz de usuario se está actualizando antes de que los datos hayan llegado. Dado que resultLiveData está cambiando antes de la request y, por lo tanto, todavía no hay datos. ¿Simplemente cómo puedo observar livedata pagedlist?

Finalmente, encontré una solución funcional, pero no creo que sea la mejor. Entonces, si tiene alguna idea, no dude en responder. Aquí está mi solución:

Dejé de envolver mis datos de PagedList con MediatorLiveData . Todavía dejo mi rest de datos en vivo ( isLoadingLiveData, isEmptyLiveData, errorLiveData ) como MediatorLiveData pero agregué su fuente cuando mi idea inicial, PagedList LiveData, se inicializó. Aquí está el código:

 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 } 
  • ¿Por qué el comstackdor de Kotlin requiere el inicializador explícito de la propiedad var?
  • ¿Cómo comparar un progtwig de Kotlin?
  • `break` y` continue` en `forEach` en Kotlin
  • ¿Qué configuration regional se usa para las templates de cadena de kotlin?
  • Constructor de class de datos con dos constructores diferentes en Kotlin
  • ¿Por qué estoy obligado a usar? en una combinación de controles nulos?
  • ¿Qué equivalentes de Java 8 Stream.collect están disponibles en la biblioteca estándar de Kotlin?
  • La reference de identificación de Kotlin Textview no funciona con caracteres no ingleses
  • RxJava 2 requiere un tipo de retorno Observable diferente de RxJava 1 (Kotlin)
  • No se pueden reutilizar los parameters de la function
  • La precisión de DecimalFormat no funciona correctamente