Ce guide s'appuie sur la présentation de la bibliothèque Paging, qui explique comment présenter des listes d'informations aux utilisateurs dans l'interface utilisateur de votre application, en particulier lorsque ces informations changent.
Connecter votre UI à votre modèle de vue
Vous pouvez connecter une instance de LiveData<PagedList>
à un PagedListAdapter
, comme indiqué dans l'extrait de code suivant :
Kotlin
class ConcertActivity : AppCompatActivity() { private val adapter = ConcertAdapter() // Use the 'by viewModels()' Kotlin property delegate // from the activity-ktx artifact private val viewModel: ConcertViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState); viewModel.concerts.observe(this, Observer { adapter.submitList(it) }) } }
Java
public class ConcertActivity extends AppCompatActivity { private ConcertAdapter adapter = new ConcertAdapter(); private ConcertViewModel viewModel; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); viewModel = new ViewModelProvider(this).get(ConcertViewModel.class); viewModel.concertList.observe(this, adapter::submitList); } }
Lorsque les sources de données fournissent de nouvelles instances de PagedList
, l'activité envoie ces objets à l'adaptateur. L'intégration de PagedListAdapter
définit le mode de calcul des mises à jour et gère automatiquement la pagination et la vérification différentielle ("diffing") des listes. ViewHolder
ne doit donc être lié qu'à un élément donné :
Kotlin
class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null. holder.bindTo(concert) } companion object { private val DIFF_CALLBACK = ... // See Implement the diffing callback section. } }
Java
public class ConcertAdapter extends PagedListAdapter<Concert, ConcertViewHolder> { protected ConcertAdapter() { super(DIFF_CALLBACK); } @Override public void onBindViewHolder(@NonNull ConcertViewHolder holder, int position) { Concert concert = getItem(position); // Note that "concert" can be null if it's a placeholder. holder.bindTo(concert); } private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = ... // See Implement the diffing callback section. }
Le PagedListAdapter
gère les événements de chargement de page à l'aide d'un objet PagedList.Callback
. Lorsque l'utilisateur fait défiler la page, PagedListAdapter
appelle PagedList.loadAround()
pour fournir des indications au PagedList
sous-jacent pour savoir quels éléments il doit récupérer à partir de DataSource
.
Intégrer le rappel de vérification différentielle ("diffing")
L'exemple suivant montre une intégration manuelle de areContentsTheSame()
, qui compare les champs d'objet pertinents :
Kotlin
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id == newItem.id // If you use the "==" operator, make sure that the object implements // .equals(). Alternatively, write custom data comparison logic here. override fun areContentsTheSame( oldItem: Concert, newItem: Concert) = oldItem == newItem }
Java
private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK = new DiffUtil.ItemCallback<Concert>() { @Override public boolean areItemsTheSame(Concert oldItem, Concert newItem) { // The ID property identifies when items are the same. return oldItem.getId() == newItem.getId(); } @Override public boolean areContentsTheSame(Concert oldItem, Concert newItem) { // Don't use the "==" operator here. Either implement and use .equals(), // or write custom data comparison logic here. return oldItem.equals(newItem); } };
Étant donné que votre adaptateur inclut la définition de comparaison d'éléments, il détecte automatiquement les modifications apportées à ces éléments lorsqu'un nouvel objet PagedList
est chargé. L'adaptateur déclenche donc des animations d'éléments efficaces dans votre objet RecyclerView
.
Diffing à l'aide d'un autre type d'adaptateur
Si vous choisissez de ne pas hériter de PagedListAdapter
, par exemple si vous utilisez une bibliothèque fournissant son propre adaptateur, vous pouvez toujours utiliser la fonction de diffing de l'adaptateur de la bibliothèque Paging en travaillant directement avec un objet AsyncPagedListDiffer
.
Fournir des espaces réservés dans votre UI
Si vous souhaitez que votre interface utilisateur affiche une liste avant que votre application n'ait fini d'extraire les données, vous pouvez présenter des éléments de liste d'espace réservé à vos utilisateurs. PagedList
gère ce cas de figure en marquant les données de l'élément de liste comme null
jusqu'à ce qu'elles soient chargées.
Les espaces réservés offrent les avantages suivants :
- Compatibilité avec les barres de défilement : la
PagedList
fournit le nombre d'éléments de liste auPagedListAdapter
. Ces informations permettent à l'adaptateur de tracer une barre de défilement qui représente toute la taille de la liste. Lorsque de nouvelles pages se chargent, la barre de défilement ne saute pas, car la taille de votre liste ne change pas. - Aucune icône de chargement requise : la taille de la liste étant déjà connue, il est inutile d'alerter les utilisateurs lorsque d'autres éléments sont en cours de chargement. Les espaces réservés eux-mêmes transmettent cette information.
Avant d'ajouter la prise en charge des espaces réservés, tenez compte des conditions préalables suivantes :
- Requiert un ensemble de données dénombrables : les instances de
DataSource
de la bibliothèque de persistance Room peuvent compter leurs articles de manière efficace. Toutefois, si vous utilisez une solution de stockage local personnalisée ou une architecture de données basée uniquement sur le réseau, il peut se révéler coûteux, voire impossible, de déterminer le nombre d'éléments qui composent votre ensemble de données. - L'adaptateur doit tenir compte des éléments non chargés : l'adaptateur ou le mécanisme de présentation que vous utilisez pour préparer la liste en cas d'augmentation doit gérer les éléments de liste vides. Par exemple, lorsque vous liez des données à un
ViewHolder
, vous devez fournir des valeurs par défaut pour représenter les données non chargées. - Requiert des vues d'élément de taille identique : si la taille des éléments de la liste peut changer en fonction de leur contenu, comme les mises à jour des réseaux sociaux, le balayage croisé d'éléments n'est pas optimal. Nous vous recommandons alors vivement de désactiver les espaces réservés.
Envoyer un commentaire
Faites-nous part de vos commentaires et de vos idées via les ressources suivantes :
- Issue Tracker
- Signalez les problèmes pour que nous puissions corriger les bugs.
Ressources supplémentaires
Pour en savoir plus sur la bibliothèque Paging, consultez les ressources suivantes.
Exemples
Ateliers de programmation
Vidéos
- Android Jetpack : gérez des listes infinies avec RecyclerView et Paging (Google I/O 2018)
- Android Jetpack : Paging
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Présentation de la bibliothèque Paging 2
- Effectuer une migration vers Paging 3
- Recueillir des données paginées