Effectuer une migration vers Paging 3

Paging 3 diffère considérablement des versions précédentes de la bibliothèque Paging. Cette version fournit des fonctionnalités améliorées et résout les problèmes courants liés à l'utilisation de Paging 2. Si votre application utilise déjà une version antérieure de la bibliothèque Paging, poursuivez votre lecture pour en savoir plus au sujet de la migration vers Paging 3.

Si Paging 3 est la première version de la bibliothèque Paging que vous utilisez dans votre application, consultez Charger et afficher les données paginées pour obtenir des informations de base sur l'utilisation.

Avantages de la migration vers Paging 3

Paging 3 inclut les fonctionnalités suivantes, qui n'étaient pas présentes dans les versions précédentes de la bibliothèque :

  • Prise en charge de premier ordre des coroutines Kotlin et Flow.
  • Prise en charge du chargement asynchrone à l'aide des rôles primitifs Single ou Guava ListenableFuture.
  • Indicateurs d'erreur et d'état de chargement intégrés pour la conception d'interface utilisateur responsive, y compris la fonctionnalité de nouvelle tentative et d'actualisation.
  • Améliorations apportées à la couche de dépôt, y compris la prise en charge de l'annulation et une interface de source de données simplifiée.
  • Améliorations apportées à la couche de présentation, aux séparateurs de liste et aux transformations de page personnalisées, ainsi qu'aux en-têtes et aux pieds de page d'état de chargement.

Migrer votre application vers Paging 3

Pour une migration complète vers Paging 3, vous devez migrer les trois principaux composants de Paging 2 :

  • Classes DataSource
  • PagedList
  • PagedListAdapter

Cependant, certains composants de Paging 3 sont rétrocompatibles avec les versions précédentes de Paging. En particulier, l'API PagingSource de Paging 3 peut servir de source de données pour LivePagedListBuilder et RxPagedListBuilder d'anciennes versions. De même, l'API Pager peut utiliser d'anciens objets DataSource avec la méthode asPagingSourceFactory(). Cela signifie que vous disposez des options de migration suivantes :

  • Vous pouvez migrer votre DataSource vers PagingSource, mais ne pas modifier le reste de votre implémentation Paging.
  • Vous pouvez migrer PagedList et PagedListAdapter, mais utiliser l'ancienne API DataSource.
  • Vous pouvez migrer l'implémentation complète de Paging pour migrer entièrement votre application vers Paging 3.

Les sections de cette page expliquent comment migrer des composants Paging sur chaque couche de votre application.

Classes DataSource

Cette section décrit toutes les modifications nécessaires pour migrer une ancienne implémentation de Paging vers PagingSource.

Les PageKeyedDataSource, PositionalDataSource et ItemKeyedDataSource de Paging 2 sont tous combinés dans l'API PagingSource de Paging 3. Les méthodes de chargement de toutes les anciennes classes d'API sont regroupées dans une seule méthode load() dans PagingSource. Cela réduit la duplication de code, car une grande partie de la logique entre les méthodes de chargement dans les implémentations des anciennes classes d'API est souvent identique.

Tous les paramètres de méthode de chargement sont remplacés dans Paging 3 par une classe scellée LoadParams, qui inclut des sous-classes pour chaque type de chargement. Si vous devez différencier les types de chargement de votre méthode load(), vérifiez quelle sous-classe de LoadParams a été transmise : LoadParams.Refresh, LoadParams.Prepend ou LoadParams.Append.

Pour en savoir plus sur l'implémentation de PagingSource, consultez Définir une source de données.

Clés d'actualisation

Les implémentations de PagingSource doivent définir la manière dont les actualisations reprennent à partir du milieu des données paginées chargées. Pour ce faire, implémentez getRefreshKey() pour mapper la clé initiale correcte en utilisant state.anchorPosition comme dernier index consulté.

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

Transformations de listes

Dans les anciennes versions de la bibliothèque Paging, la transformation des données paginées repose sur les méthodes suivantes :

  • DataSource.map()
  • DataSource.mapByPage()
  • DataSource.Factory.map()
  • DataSource.Factory.mapByPage()

Dans Paging 3, toutes les transformations sont appliquées en tant qu'opérateurs dans PagingData. Si vous utilisez l'une des méthodes de la liste précédente pour transformer votre liste paginée, vous devez déplacer votre logique de transformation depuis la DataSource vers les PagingData lors de la création du Pager à l'aide de votre nouvelle PagingSource.

Pour en savoir plus sur l'application de transformations aux données paginées à l'aide de Paging 3, consultez Transformer des flux de données.

PagedList

Cette section décrit toutes les modifications nécessaires pour migrer une ancienne implémentation de Paging afin d'utiliser Pager et PagingData dans Paging 3.

Classes PagedListBuilder

PagingData remplace la PagedList existante de Paging 2. Pour migrer vers PagingData, vous devez mettre à jour les éléments suivants :

  • La configuration de Paging a été déplacée de PagedList.Config vers PagingConfig.
  • LivePagedListBuilder et RxPagedListBuilder ont été combinés en une seule classe Pager.
  • Pager expose un élément Flow<PagingData> observable avec sa propriété .flow. Les variantes RxJava et LiveData sont également disponibles en tant que propriétés d'extension, qui peuvent être appelées depuis Java via des méthodes statiques, et sont fournies respectivement depuis les modules paging-rxjava* et paging-runtime.

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);

Pour en savoir plus sur la configuration d'un flux réactif d'objets PagingData à l'aide de Paging 3, consultez Configurer un flux de PagingData.

BoundaryCallback pour les sources superposées

Dans Paging 3, RemoteMediator remplace PagedList.BoundaryCallback en tant que gestionnaire de la pagination depuis le réseau et la base de données.

Pour en savoir plus sur l'utilisation de RemoteMediator pour parcourir les pages du réseau et de la base de données dans Paging 3, consultez l'atelier de programmation Android Paging.

PagedListAdapter

Cette section décrit toutes les modifications nécessaires pour migrer une ancienne implémentation de Paging afin d'utiliser les classes PagingDataAdapter ou AsyncPagingDataDiffer de Paging 3.

Paging 3 fournit PagingDataAdapter pour gérer les nouveaux flux réactifs PagingData. À part cela, PagedListAdapter et PagingDataAdapter possèdent la même interface. Pour passer de PagedListAdapter à PagingDataAdapter, modifiez votre implémentation de PagedListAdapter pour étendre PagingDataAdapter à la place.

Pour en savoir plus sur PagingDataAdapter, consultez Définir un adaptateur RecyclerView.

AsyncPagedListDiffer

Si vous utilisez actuellement une implémentation RecyclerView.Adapter personnalisée avec AsyncPagedListDiffer, migrez votre implémentation pour qu'elle utilise la valeur AsyncPagingDataDiffer fournie dans Paging 3 :

Kotlin

AsyncPagingDataDiffer(diffCallback, listUpdateCallback)

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Java

new AsyncPagingDataDiffer(diffCallback, listUpdateCallback);

Ressources supplémentaires

Pour en savoir plus sur la bibliothèque Paging, consultez ces ressources supplémentaires :

Ateliers de programmation

Exemples