Paging 3 es bastante diferente de las versiones anteriores de la biblioteca de paginación. Esta versión proporciona funciones mejoradas y aborda las dificultades comunes del uso de Paging 2. Si tu app ya usa una versión anterior de la biblioteca de paginación, lee esta página para obtener más información sobre la migración a Paging 3.
Si Paging 3 es la primera versión de la biblioteca de paginación que usas en tu app, consulta Cómo cargar y mostrar datos paginados para obtener información básica de uso.
Beneficios de migrar a Paging 3
Paging 3 incluye las siguientes características que no estaban presentes en versiones anteriores de la biblioteca:
- Compatibilidad de primer nivel con las corrutinas y el flujo de Kotlin
- Compatibilidad con la carga asíncrona mediante los tipos primitivos
Single
de RxJava oListenableFuture
de Guava - Estado de carga integrado y señales de error para un diseño de IU adaptable, incluida la función de reintento y actualización
- Mejoras en la capa del repositorio, como la compatibilidad para la cancelación y una interfaz de fuente de datos simplificada
- Mejoras en la capa de la presentación, los separadores de lista, las transformaciones de páginas personalizadas y el estado de carga de encabezados y pies de página
Cómo migrar tu app a Paging 3
Para realizar la migración completa a Paging 3, debes migrar los tres componentes principales de Paging 2:
- Clases
DataSource
PagedList
PagedListAdapter
Sin embargo, algunos componentes de Paging 3 son retrocompatibles con versiones anteriores de Paging. En particular, la API de PagingSource
de Paging 3 puede ser una fuente de datos para LivePagedListBuilder
y RxPagedListBuilder
de versiones anteriores. Del mismo modo, la API de Pager
puede usar objetos DataSource
más antiguos con el método asPagingSourceFactory()
. Esto significa que tienes las siguientes opciones de migración:
- Puedes migrar tu
DataSource
aPagingSource
, pero no modificar el resto de tu implementación de Paging. - Puedes migrar
PagedList
yPagedListAdapter
, pero seguir usando la API deDataSource
anterior. - Puedes migrar toda la implementación de Paging para migrar completamente tu app a Paging 3.
En las secciones de esta página, se explica cómo migrar los componentes de Paging de cada capa de tu app.
Clases DataSource
En esta sección, se describen todos los cambios necesarios para migrar una implementación de Paging más antigua a fin de usar PagingSource
.
Los elementos PageKeyedDataSource
, PositionalDataSource
y ItemKeyedDataSource
de Paging 2 se combinan en la API de PagingSource
de Paging 3. Los métodos de carga de todas las clases de API anteriores se combinan en un único método load()
en PagingSource
. Esto reduce la duplicación de código, ya que gran parte de la lógica de los métodos de carga en las implementaciones de las clases de API anteriores suele ser idéntica.
Todos los parámetros de métodos de carga se reemplazan en Paging 3 con una clase sellada LoadParams
, que incluye subclases para cada tipo de carga. Si necesitas diferenciar los tipos de carga de tu método load()
, verifica qué subclase de LoadParams
se pasó en LoadParams.Refresh
, LoadParams.Prepend
o LoadParams.Append
.
Para obtener más información sobre la implementación de PagingSource
, consulta Cómo definir una fuente de datos.
Actualiza las claves
Las implementaciones de PagingSource
deben definir cómo se reanudan las actualizaciones desde el medio de los datos paginados cargados. Para ello, implementa getRefreshKey()
a fin de mapear la clave inicial correcta con state.anchorPosition
como el índice al que se accedió más recientemente.
Kotlin
// Replaces ItemKeyedDataSource. override fun getRefreshKey(state: PagingState): String? { return state.anchorPosition?.let { anchorPosition -> state.getClosestItemToPosition(anchorPosition)?.id } } // Replacing PositionalDataSource. override fun getRefreshKey(state: PagingState ): Int? { return state.anchorPosition }
Java
// Replaces ItemKeyedDataSource. @Nullable @Override String getRefreshKey(state: PagingState) { Integer anchorPosition = state.anchorPosition; if (anchorPosition == null) { return null; } return state.getClosestItemToPosition(anchorPosition); } // Replaces PositionalDataSource. @Nullable @Override Integer getRefreshKey(state: PagingState ) { return state.anchorPosition; }
Java
// Replacing ItemKeyedDataSource. @Nullable @Override String getRefreshKey(state: PagingState) { Integer anchorPosition = state.anchorPosition; if (anchorPosition == null) { return null; } return state.getClosestItemToPosition(anchorPosition); } // Replacing PositionalDataSource. @Nullable @Override Integer getRefreshKey(state: PagingState ) { return state.anchorPosition; }
Transformaciones de lista
En las versiones anteriores de la biblioteca de Paging, la transformación de los datos paginados se basa en los siguientes métodos:
DataSource.map()
DataSource.mapByPage()
DataSource.Factory.map()
DataSource.Factory.mapByPage()
En Paging 3, todas las transformaciones se aplican como operadores en PagingData
. Si usas alguno de los métodos de la lista anterior para transformar tu lista paginada, debes mover la lógica de transformación de la DataSource
a los PagingData
cuando construyas la Pager
con tu PagingSource
nuevo.
Si quieres obtener más información para aplicar transformaciones a datos paginados con Paging 3, consulta Cómo transformar flujos de datos.
PagedList
En esta sección, se describen todos los cambios necesarios para migrar una implementación de Paging más antigua y usar Pager
y PagingData
en Paging 3.
Clases PagedListBuilder
PagingData
reemplaza a la PagedList
existente de Paging 2. Para migrar a PagingData
, debes actualizar lo siguiente:
- La configuración de la paginación se movió de
PagedList.Config
aPagingConfig
. LivePagedListBuilder
yRxPagedListBuilder
se combinaron en una sola clasePager
.Pager
expone unFlow<PagingData>
observable con su propiedad.flow
. Las variantes de RxJava y LiveData también están disponibles como propiedades de extensión, que se pueden llamar desde Java mediante métodos estáticos y se proporcionan desde los módulospaging-rxjava*
ypaging-runtime
, respectivamente.
Kotlin
val flow = Pager( // Configure how data is loaded by passing additional properties to // PagingConfig, such as prefetchDistance. PagingConfig(pageSize = 20) ) { ExamplePagingSource(backend, query) }.flow .cachedIn(viewModelScope)
Java
// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact. CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel); Pager<Integer, User> pager = Pager<>( new PagingConfig(/* pageSize = */ 20), () -> ExamplePagingSource(backend, query)); Flowable<PagingData<User>> flowable = PagingRx.getFlowable(pager); PagingRx.cachedIn(flowable, viewModelScope);
Java
// CoroutineScope helper provided by the lifecycle-viewmodel-ktx artifact. CoroutineScope viewModelScope = ViewModelKt.getViewModelScope(viewModel); Pager<Integer, User> pager = Pager<>( new PagingConfig(/* pageSize = */ 20), () -> ExamplePagingSource(backend, query)); PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), viewModelScope);
Si quieres obtener más información para configurar un flujo reactivo de objetos PagingData
con Paging 3, consulta Cómo configurar un flujo de PagingData.
BoundaryCallback para fuentes en capas
En Paging 3, RemoteMediator
reemplaza PagedList.BoundaryCallback
como un controlador de la paginación desde la red y la base de datos.
Si quieres obtener más información sobre el uso de RemoteMediator
para realizar la paginación desde la red y la base de datos en Paging 3, consulta el codelab de paginación de Android.
PagedListAdapter
En esta sección, se describen todos los cambios necesarios para migrar una implementación de Paging más antigua y usar las clases PagingDataAdapter
o AsyncPagingDataDiffer
en Paging 3.
Paging 3 proporciona PagingDataAdapter
para controlar los nuevos flujos de PagingData
reactivos. Por lo demás, PagedListAdapter
y PagingDataAdapter
tienen la misma interfaz. Para migrar de PagedListAdapter
a PagingDataAdapter
, cambia tu implementación de PagedListAdapter
para extender PagingDataAdapter
.
Para obtener más información sobre PagingDataAdapter
, consulta Cómo definir un adaptador RecyclerView.
AsyncPagedListDiffer
Si actualmente usas una implementación personalizada de RecyclerView.Adapter
con AsyncPagedListDiffer
, migra tu implementación para usar el AsyncPagingDataDiffer
proporcionado en Paging 3 en su lugar:
Kotlin
AsyncPagingDataDiffer(diffCallback, listUpdateCallback)
Java
new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);
Java
new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);
Recursos adicionales
Para obtener más información sobre la biblioteca de Paging, consulta los siguientes recursos adicionales:
Codelabs
Ejemplos
- Ejemplo de Paging de los componentes de la arquitectura de Android
- Ejemplo de Paging de los componentes de la arquitectura de Android con base de datos y red
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo cargar y mostrar datos paginados
- Cómo recopilar datos paginados
- Página de la red y la base de datos