¿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 } 
  • Compatibilidad de Kotlin con @ColorInt Java Annotation
  • Cómo get / poner Kotlin Inner Map o Mapa de map
  • Cómo convertir cadena a char en Kotlin?
  • Android Studio 2.2 no puede encontrar references para todos los files de kotlin
  • ¿Cómo colocar una extensión de Kotlin en un file de class?
  • ¿Cómo usar @DbEnumValue con Ebean en Kotlin?
  • ¿Cómo se traduce esta syntax maravillosa a kotlin?
  • ¿Por qué mi trabajo no está comenzando?
  • ¿Cómo orderar la list de objects en caso de order insensible?
  • IllegalArgumentException: savedInstanceState especificado como no nulo es nulo
  • No se puede usar el procesador de anotación local en el proyecto Android Kotlin