Architecture Components: Paging Library (Parte II) #AndroidMeetsKotlin
Francisco Manuel López Jurado Colaboraciones 03/05/2019
Siguiendo el anterior post sobre integración de Paging Library, ahora vas a llegar al 100% de la integración. De esta forma, verás las modificaciones en el repositorio, ViewModel, la creación del PagedListAdapter, la Activity y finalmente, la modificación del servicio para añadir el número de página. Como siempre, el código del proyecto puedes encontrarlo en el siguiente enlace bajo la rama “paging”. Sin más, ¡Al lío!
1.- Incluye el número de página y los elementos por página
Debes modificar:
1.1.- GithubService
El servicio ahora recibirá los dos nuevos parámetros referidos a la paginación (“page” y “per_page”) por lo que quedaría de la siguiente forma:
La implementación la puedes encontrar en el siguiente enlace.
1.2.- GithubRepoApiDataSource
El método “getGithubRepos” también debe recibir estos parámetros por lo que tienes que cambiar su declaración y la llamada al método “searchRepositories” anteriormente comentado.
El número de página será constante (ITEMS_PER_PAGE_NETWORK) y tendrá un valor de 50.
La implementación la puedes encontrar en el siguiente enlace.
2.- Cambios en el Repositorio (GithubRepository)
Este cambio será uno de los mayores que vas a realizar, por lo tanto debes seguir los siguientes pasos:
2.1.- Añadir nuevas variables a la clase
Debes añadir:
- var callback: GithubRepoBoundaryCallback. Servirá para la actualización de los nuevos datos necesarios a mostrar.
- var lastQueryInfoRequested: String. Tendrá la información de la última consulta realizada, de esta forma, si la consulta es distinta, se reseteará el número de página consultado.
2.2.- Añade los métodos “isSameQueryThanLastQuery” y “setUpLastPageNumberToQuery”
- isSameQueryThanLastQuery. Como su nombre indica, comprobará si la nueva consulta es idéntica a la anteriormente consultada.
- setUpLastPageNumberToQuery. Establecerá el número de página a consultar en base a los datos que ya hay almacenados en la base de datos.
2.3.- Actualiza el método “searchRepos”
Antes, este método sólo consultaba los datos al servicio y actualizaba los datos una vez eran obtenidos. Ahora, debes comprobar si la consulta es igual a la anterior o no, para configurar el BoundaryCallback que se encargará de rellenar tu listado.
Como segundo paso, debes obtener el DataSource.Factory desde el DataSource de Local y configurar el PagedList.Config.
La configuración será la siguiente:
- “EnablePlaceholders” = true.
- “InitialLoadSizeHint” = Constante ITEMS_PER_PAGE_DB con valor 20.
- “PageSize” = Constante ITEMS_PER_PAGE_DB con valor 50.
- “PrefetchDistance” = Constante PREFETCH_DISTANCE con valor 5.
Finalmente, una vez has creado los anteriores objetos, tienes que crear el LivePagedListBuilder, establecer el factory, config y callback creados anteriormente. Por último, llama a su método build() y retórnalo.
La implementación quedaría de la siguiente forma y la puedes encontrar en el siguiente enlace:
3.- Cambios en el ViewModel (SearchRepoViewModel)
Realizarás dos cambios:
- La variable githubReposListLiveData tiene que pasar de tipo LiveData<List<GithubRepoDomain>> a LiveData<PagedList<GithubRepoDomain>>
- El método “search” debe retornar LiveData<PagedList<GithubRepoDomain>> ya que lo usarás en la declaración de la variable anterior haciendo uso del método “Transformations.switchMap”.
La implementación la puedes encontrar en el siguiente enlace.
4.-Creación del PagedListAdapter (GithubRepoAdapter)
El adapter es muy similar a cualquiera de los que has creado anteriormente, sólo tiene un único cambio y debe extender de PagedListAdapter. Ten en cuenta que su constructor recibe un DiffUtil.ItemCallback que comprueba si los elementos son iguales o si el contenido de los mismos es idéntico.
Para la implementación del DiffUtil debes crear un “companion object” y quedaría tal que así:
La implementación del resto del adapter puedes encontrarla en el siguiente enlace.
5.- Cambios en la Activity (MainActivity)
Sólo debes realizar un único cambio, el Observer debe pasar de ser “Observer<List<GithubRepoDomain>>” a “Observer<PagedList<GithubRepoDomain>>”.
Además, debes crear el adapter y vincularlo al RecyclerView, lo que hará posible visualizar los datos y ver si la paginación funciona correctamente.
La implementación de cómo quedaría puedes verla en el siguiente enlace.
Se terminó
En resumen, si has seguido los pasos minuciosamente detallados en este y el anterior post (Architecture Components: Paging Library (Parte I) #AndroidMeetsKotlin de Fran López), habrás pasado de tener una simple carga de datos fija a una paginación dinámica y rápida. Esta librería simplifica mucho el desarrollo e integración de este tipo de comportamientos y hace mucho más fácil su implementación. En definitiva, Architecture Components sigue haciéndote la vida mucho más fácil.