Kotlin Fundamentals 07.2: DiffUtil et liaison de données avec RecyclerView

Cet atelier de programmation fait partie du cours Android Kotlin Fundamentals. Vous tirerez le meilleur parti de ce cours si vous suivez les ateliers de programmation dans l'ordre. Tous les ateliers de programmation du cours sont répertoriés sur la page de destination des ateliers de programmation Android Kotlin Fundamentals.

Présentation

Dans l'atelier de programmation précédent, vous avez mis à jour l'application TrackMySleepQuality pour afficher des données sur la qualité du sommeil dans un RecyclerView. Les techniques que vous avez apprises lors de la création de votre premier RecyclerView sont suffisantes pour la plupart des RecyclerViews qui affichent des listes simples qui ne sont pas trop volumineuses. Cependant, il existe un certain nombre de techniques qui rendent RecyclerView plus efficace pour les longues listes, et qui facilitent la gestion et l'extension de votre code aux listes et grilles complexes.

Dans cet atelier de programmation, vous allez utiliser l'application de suivi du sommeil de l'atelier de programmation précédent. Vous allez apprendre un moyen plus efficace de mettre à jour la liste des données sur le sommeil et vous apprendrez à utiliser la liaison de données avec RecyclerView. (Si vous ne disposez pas de l'application lors de l'atelier de programmation précédent, vous pouvez télécharger le code de démarrage pour cet atelier.)

Ce que vous devez déjà savoir

  • Créer une interface utilisateur de base à l'aide d'une activité, de fragments et de vues
  • Navigation entre les fragments et utilisation de safeArgs pour transmettre des données entre fragments.
  • Affichez des modèles, et découvrez les usines de modèles, les transformations et LiveData ainsi que leurs observateurs.
  • Créer une base de données Room, créer un DAO et définir des entités
  • Utiliser des coroutines pour les bases de données et d'autres tâches de longue durée
  • Implémenter un RecyclerView de base avec une Adapter, une ViewHolder et une mise en page

Points abordés

  • Utiliser DiffUtil pour mettre à jour efficacement une liste affichée par RecyclerView
  • Utiliser la liaison de données avec RecyclerView.
  • Utiliser des adaptateurs de liaison pour transformer les données

Objectifs de l'atelier

  • Créez une application basée sur l'application TrackMySleepQuality de l'atelier de programmation précédent de cette série.
  • Mettez à jour SleepNightAdapter pour mettre à jour efficacement la liste avec DiffUtil.
  • Implémentez la liaison de données pour RecyclerView à l'aide d'adaptateurs de liaison pour transformer les données.

L'application de suivi du sommeil comporte deux écrans, représentés par des fragments, comme illustré dans la figure ci-dessous.

Le premier écran, affiché à gauche, comporte des boutons permettant de démarrer et d'arrêter le suivi. Certaines des données sur le sommeil de l'utilisateur s'affichent à l'écran. Le bouton Effacer supprime définitivement toutes les données collectées par l'utilisateur. Le deuxième écran, à droite, permet de sélectionner un niveau de qualité du sommeil.

Cette application est conçue pour utiliser un contrôleur d'interface utilisateur (ViewModel) et LiveData, ainsi qu'une base de données Room pour conserver les données de sommeil.

Les données sur le sommeil s'affichent dans un RecyclerView. Dans cet atelier de programmation, vous allez créer la partie DiffUtil et la liaison de données pour RecyclerView. Après cet atelier de programmation, votre application se présentera exactement de la même manière, mais elle sera plus efficace et plus évolutive.

Vous pouvez continuer à utiliser l'application SleepTracker depuis l'atelier de programmation précédent ou télécharger l'application RecyclerViewDiffUtilDataBinding-Starter sur GitHub.

  1. Si nécessaire, téléchargez l'application RecyclerViewDiffUtilDataBinding-Starter à partir de GitHub et ouvrez le projet dans Android Studio.
  2. Exécutez l'application.
  3. Ouvrez le fichier SleepNightAdapter.kt.
  4. Inspectez le code pour vous familiariser avec la structure de l'application. Reportez-vous au schéma ci-dessous pour découvrir un résumé de l'utilisation de RecyclerView avec le modèle d'adaptateur pour afficher les données sur le sommeil à l'utilisateur.

  • À partir des entrées utilisateur, l'application crée une liste d'objets SleepNight. Chaque objet SleepNight représente une seule nuit, sa durée et sa qualité.
  • Le SleepNightAdapter adapte la liste des objets SleepNight en un élément que RecyclerView peut utiliser et afficher.
  • L'adaptateur SleepNightAdapter produit des ViewHolders qui contiennent les vues, les données et les métadonnées d'affichage de l'outil de recyclage pour afficher les données.
  • RecyclerView utilise SleepNightAdapter pour déterminer le nombre d'éléments à afficher (getItemCount()). RecyclerView utilise onCreateViewHolder() et onBindViewHolder() pour associer les vues aux données.

La méthode notificationDataSetChanged() est inefficace

Pour indiquer à RecyclerView qu'un élément de la liste a changé et doit être mis à jour, le code actuel appelle notifyDataSetChanged() dans le SleepNightAdapter, comme illustré ci-dessous.

var data =  listOf<SleepNight>()
   set(value) {
       field = value
       notifyDataSetChanged()
   }

Cependant, notifyDataSetChanged() indique à RecyclerView que toute la liste est potentiellement non valide. Par conséquent, RecyclerView réorganise et redessine tous les éléments de la liste, y compris ceux qui ne sont pas visibles à l'écran. Cela représente beaucoup de travail inutile. Pour les listes volumineuses ou complexes, ce processus peut prendre suffisamment de temps pour que l'écran clignote ou s'arrête lorsque l'utilisateur fait défiler la liste.

Pour résoudre ce problème, vous pouvez indiquer à RecyclerView ce qui a changé. RecyclerView peut ensuite mettre à jour uniquement les vues qui ont été modifiées à l'écran.

RecyclerView dispose d'une API enrichie pour mettre à jour un seul élément. Vous pouvez utiliser l'attribut notifyItemChanged() pour indiquer à RecyclerView qu'un article a été modifié ou utiliser des fonctions similaires pour les articles ajoutés, supprimés ou déplacés. Vous pouvez le faire manuellement, mais cette tâche serait simple et pourrait impliquer un peu de code.

Heureusement, il y a une meilleure façon de procéder.

DiffUtil est efficace et fait le maximum pour vous

RecyclerView comporte une classe DiffUtil qui permet de calculer les différences entre deux listes. DiffUtil s'appuie sur une ancienne liste et une nouvelle pour identifier ce qui est différent. Elle recherche les éléments ajoutés, supprimés ou modifiés. Elle utilise ensuite un algorithme appelé Eugene W. L'algorithme de différence de Myers permet de déterminer le nombre minimal de modifications à apporter à l'ancienne liste pour générer la nouvelle liste.

Une fois que DiffUtil a identifié les éléments modifiés, RecyclerView peut utiliser ces informations pour mettre à jour uniquement les éléments modifiés, ajoutés, supprimés ou déplacés, ce qui est beaucoup plus efficace que de répéter toute la liste.

Dans cette tâche, vous allez mettre à jour SleepNightAdapter pour utiliser DiffUtil afin d'optimiser le RecyclerView pour les modifications apportées aux données.

Étape 1: Implémentez la fonctionnalité SleepNightDiffCallback

Pour utiliser la fonctionnalité de la classe DiffUtil, étendez DiffUtil.ItemCallback.

  1. Ouvrez SleepNightAdapter.kt.
  2. Sous la définition complète de la classe pour SleepNightAdapter, créez une classe de premier niveau appelée SleepNightDiffCallback qui représente une extension de DiffUtil.ItemCallback. Transmettre SleepNight en tant que paramètre générique
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
  1. Placez le curseur dans le nom de la classe SleepNightDiffCallback.
  2. Appuyez sur Alt+Enter (Option+Enter sur Mac), puis sélectionnez Mettre en œuvre les membres.
  3. Dans la boîte de dialogue qui s'ouvre, effectuez un clic gauche pour sélectionner les méthodes areItemsTheSame() et areContentsTheSame(), puis cliquez sur OK.

    Cette action génère des bouchons dans SleepNightDiffCallback pour les deux méthodes, comme illustré ci-dessous. DiffUtil utilise ces deux méthodes pour comprendre comment la liste et les éléments ont changé.
    override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
  1. Dans areItemsTheSame(), remplacez le TODO par le code qui teste si les deux éléments SleepNight transmis, oldItem et newItem, sont identiques. Si les éléments ont le même nightId, ils sont identiques. Vous devez donc renvoyer true. Sinon, renvoyez false. DiffUtil utilise ce test pour déterminer si un élément a été ajouté, supprimé ou déplacé.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem.nightId == newItem.nightId
}
  1. Dans areContentsTheSame(), vérifiez si oldItem et newItem contiennent les mêmes données (c'est-à-dire s'ils sont égaux). Ce contrôle d'égalité vérifiera tous les champs, car SleepNight est une classe de données. Les classes Data définissent automatiquement equals et quelques autres méthodes pour vous. En cas de différences entre oldItem et newItem, ce code indique à DiffUtil que l'élément a été mis à jour.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem == newItem
}

Il s'agit d'un schéma courant pour utiliser une RecyclerView pour afficher une liste qui change. RecyclerView fournit une classe d'adaptateur, ListAdapter, qui vous aide à créer un adaptateur RecyclerView secondé par une liste.

ListAdapter effectue le suivi de la liste pour vous et avertit l'adaptateur lorsque la liste est mise à jour.

Étape 1: Modifiez votre adaptateur pour étendre la classe

  1. Dans le fichier SleepNightAdapter.kt, modifiez la signature de classe de SleepNightAdapter pour étendre ListAdapter.
  2. Si vous y êtes invité, importez androidx.recyclerview.widget.ListAdapter.
  3. Ajoutez SleepNight comme premier argument du ListAdapter, avant SleepNightAdapter.ViewHolder.
  4. Ajoutez SleepNightDiffCallback() en tant que paramètre au constructeur. ListAdapter permettra de déterminer ce qui a changé dans la liste. Votre signature de classe SleepNightAdapter terminée doit ressembler à ce qui suit.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. Dans la classe SleepNightAdapter, supprimez le champ data, y compris le setter. Vous n'en avez plus besoin, car ListAdapter effectue le suivi de la liste pour vous.
  2. Supprimez le remplacement de getItemCount(), car ListAdapter met en œuvre cette méthode pour vous.
  3. Pour résoudre l'erreur dans onBindViewHolder(), modifiez la variable item. Au lieu d'utiliser data pour obtenir un item, appelez la méthode getItem(position) fournie par le ListAdapter.
val item = getItem(position)

Étape 2: Utilisez updateList() pour maintenir la liste à jour

Votre code doit indiquer à ListAdapter lorsqu'une liste modifiée est disponible. ListAdapter fournit une méthode appelée submitList() pour indiquer à ListAdapter qu'une nouvelle version de la liste est disponible. Lorsque cette méthode est appelée, la ListAdapter compare la nouvelle liste par rapport à l'ancienne et détecte les éléments ajoutés, supprimés, déplacés ou modifiés. Ensuite, le ListAdapter met à jour les éléments affichés par RecyclerView.

  1. Ouvrez SleepTrackerFragment.kt.
  2. Dans onCreateView(), dans l'observateur sur sleepTrackerViewModel, recherchez l'erreur où la variable data que vous avez supprimée est référencée.
  3. Remplacez adapter.data = it par un appel vers adapter.submitList(it). Le code mis à jour est affiché ci-dessous.

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.submitList(it)
   }
})
  1. Exécutez votre application. Elle est plus rapide, peut-être pas notable si votre liste est petite.

Dans cette tâche, vous allez utiliser la même technique que dans les ateliers de programmation précédents pour configurer la liaison de données, et vous éliminez les appels à findViewById().

Étape 1: Ajoutez une liaison de données au fichier de mise en page

  1. Ouvrez le fichier de mise en page list_item_sleep_night.xml dans l'onglet Text.
  2. Placez le curseur sur le tag ConstraintLayout et appuyez sur Alt+Enter (Option+Enter sur Mac). Le menu d'intent (menu de réparation rapide) s'affiche.
  3. Sélectionnez Convertir en mise en page de liaison de données. Cette action encapsule la mise en page dans <layout> et ajoute une balise <data> à l'intérieur.
  4. Si nécessaire, faites défiler la page vers le haut pour déclarer une variable nommée sleep dans la balise <data>.
  5. Utilisez le typenom complet (SleepNight com.example.android.trackmysleepquality.database.SleepNight). Votre balise <data> terminée doit ressembler à ce qui suit.
   <data>
        <variable
            name="sleep"
            type="com.example.android.trackmysleepquality.database.SleepNight"/>
    </data>
  1. Pour forcer la création de l'objet Binding, sélectionnez Build > Clean Project (Compiler &gt ; Effacer le projet), puis sélectionnez Build > Rebuild Project. Si le problème persiste, sélectionnez Fichier &gt ; Invalidation des caches / Redémarrer. L'objet de liaison ListItemSleepNightBinding et le code associé sont ajoutés aux fichiers générés du projet.

Étape 2: Augmentez la mise en page à l'aide de la liaison de données

  1. Ouvrez SleepNightAdapter.kt.
  2. Dans la classe ViewHolder, recherchez la méthode from().
  3. Supprimez la déclaration de la variable view.

Code à supprimer:

val view = layoutInflater
       .inflate(R.layout.list_item_sleep_night, parent, false)
  1. Où se trouvait la variable view, définissez une nouvelle variable appelée binding qui gonfle l'objet de liaison ListItemSleepNightBinding, comme illustré ci-dessous. Effectuez l'importation nécessaire de l'objet lié.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
  1. À la fin de la fonction, au lieu de renvoyer view, renvoyez binding.
return ViewHolder(binding)
  1. Pour résoudre l'erreur, placez le curseur sur le mot binding. Appuyez sur Alt+Enter (Option+Enter sur un Mac) pour ouvrir le menu d'intent.
  1. Sélectionnez Modifier le paramètre 'itemView' type du constructeur principal de la classe 'ViewHolder' et 'ListItemSleepNightBinding'. Cela met à jour le type de paramètre de la classe ViewHolder.

  1. Faites défiler la page jusqu'à la définition de classe de la propriété ViewHolder pour voir le changement dans la signature. Une erreur s'affiche pour itemView, car vous avez remplacé itemView par binding dans la méthode from().

    Dans la définition de classe ViewHolder, effectuez un clic droit sur l'une des occurrences de itemView, puis sélectionnez Refactor (Refactoriser) et Rename (Renommer). Remplacez le nom par binding.
  2. Ajoutez le préfixe val au paramètre du constructeur binding pour en faire une propriété.
  3. Dans l'appel de la classe parente, RecyclerView.ViewHolder, remplacez le paramètre binding par binding.root. Vous devez transmettre une View, et binding.root est la ConstraintLayout racine dans la mise en page de votre élément.
  4. Votre déclaration de classe terminée doit ressembler à ce qui suit.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){

Vous verrez également une erreur pour les appels au findViewById(), et vous allez résoudre ce problème.

Étape 3: Remplacer findViewById()

Vous pouvez désormais mettre à jour les propriétés sleepLength, quality et qualityImage pour utiliser l'objet binding au lieu de findViewById().

  1. Modifiez les initialisations de sleepLength, qualityString et qualityImage pour utiliser les vues de l'objet binding, comme illustré ci-dessous. Après cette date, votre code ne devrait plus afficher d'erreurs.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage

Avec l'objet de liaison en place, vous n'avez plus besoin de définir les propriétés sleepLength, quality et qualityImage. DataBinding mettra en cache les recherches. Il n'est donc pas nécessaire de déclarer ces propriétés.

  1. Effectuez un clic droit sur les noms de propriétés sleepLength, quality et qualityImage. Sélectionnez Refactor > Inline (Refactoriser et intégrer), ou appuyez sur Control+Command+N (Option+Command+N sur Mac).
  2. Exécutez votre application. (Vous devrez peut-être nettoyer et recompiler votre projet s'il contient des erreurs).

Dans cette tâche, vous allez mettre à niveau votre application pour utiliser une liaison de données avec des adaptateurs de liaison et définir les données dans vos vues.

Dans un atelier de programmation précédent, vous avez utilisé la classe Transformations pour utiliser LiveData et générer des chaînes formatées à afficher dans les vues de texte. Toutefois, si vous devez lier différents types ou types complexes, vous pouvez fournir des adaptateurs de liaison pour faciliter la liaison de données avec ces types. Les adaptateurs de liaison vous permettent d'adapter vos données à un format que la liaison de données peut utiliser pour lier une vue, comme du texte ou une image.

Vous allez mettre en œuvre trois adaptateurs de liaison (un pour l'image de qualité et un pour chaque champ de texte). En résumé, pour déclarer un adaptateur de liaison, vous devez définir une méthode qui utilise un élément et une vue, puis l'annoter avec @BindingAdapter. Dans le corps de la méthode, vous implémentez la transformation. En langage Kotlin, vous pouvez écrire un adaptateur de liaison en tant que fonction d'extension sur la classe de vue qui reçoit les données.

Étape 1: Créez des adaptateurs de liaison

Notez que vous devez importer un certain nombre de classes lors de l'étape et que celles-ci ne seront pas décrites individuellement.

  1. Ouvrez SleepNightAdapater.kt.
  2. Dans la classe ViewHolder, recherchez la méthode bind() et rappelez-la en quoi consiste cette méthode. Vous allez utiliser le code qui calcule les valeurs pour binding.sleepLength, binding.quality et binding.qualityImage pour l'utiliser dans l'adaptateur. Pour l'instant, laissez le code tel quel. Vous le déplacerez plus tard.
  3. Dans le package sleeptracker, créez et ouvrez un fichier appelé BindingUtils.kt.
  4. Déclarez une fonction d'extension sur TextView, appelée setSleepDurationFormatted, puis transmettez une valeur SleepNight. Elle servira d'adaptateur pour le calcul et la mise en forme de la durée de sommeil.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
  1. Dans le corps de setSleepDurationFormatted, lier les données à la vue comme vous l'avez fait dans ViewHolder.bind(). Appelez convertDurationToFormatted(), puis définissez text du TextView sur le texte mis en forme. Étant donné qu'il s'agit d'une fonction d'extension de TextView, vous pouvez accéder directement à la propriété text.
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
  1. Pour indiquer la liaison de données à propos de cet adaptateur de liaison, annotez la fonction avec @BindingAdapter.
  2. Cette fonction est l'adaptateur de l'attribut sleepDurationFormatted. Transmettez sleepDurationFormatted comme argument à @BindingAdapter.
@BindingAdapter("sleepDurationFormatted")
  1. Le deuxième adaptateur définit la qualité du sommeil en fonction de la valeur d'un objet SleepNight. Créez une fonction d'extension appelée setSleepQualityString() sur TextView et transmettez un SleepNight.
  2. Dans le corps, lier les données à la vue comme vous l'avez fait dans ViewHolder.bind() Appelez convertNumericQualityToString et définissez text.
  3. Annotez la fonction avec @BindingAdapter("sleepQualityString").
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
   text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
  1. Le troisième adaptateur de liaison définit l'image sur une vue d'image. Créez la fonction d'extension sur ImageView, appelez setSleepImage et utilisez le code de ViewHolder.bind(), comme indiqué ci-dessous.
@BindingAdapter("sleepImage")
fun ImageView.setSleepImage(item: SleepNight) {
   setImageResource(when (item.sleepQuality) {
       0 -> R.drawable.ic_sleep_0
       1 -> R.drawable.ic_sleep_1
       2 -> R.drawable.ic_sleep_2
       3 -> R.drawable.ic_sleep_3
       4 -> R.drawable.ic_sleep_4
       5 -> R.drawable.ic_sleep_5
       else -> R.drawable.ic_sleep_active
   })
}

Étape 2: Mettez à jour l'adaptateur SleepNightAdapter

  1. Ouvrez SleepNightAdapter.kt.
  2. Supprimez tout le contenu de la méthode bind(), car vous pouvez désormais utiliser la liaison de données et vos nouveaux adaptateurs pour réaliser cette opération.
fun bind(item: SleepNight) {
}
  1. Dans bind(), attribuez un sommeil à item, car vous devez indiquer à l'objet de liaison le nouveau SleepNight.
binding.sleep = item
  1. Sous cette ligne, ajoutez binding.executePendingBindings(). Cet appel est une optimisation qui demande à la liaison de données d'exécuter immédiatement les liaisons en attente. Nous vous recommandons de toujours appeler executePendingBindings() lorsque vous utilisez des adaptateurs de liaison dans un RecyclerView, car cela peut accélérer légèrement le dimensionnement des vues.
 binding.executePendingBindings()

Étape 3: Ajoutez des liaisons à la mise en page XML

  1. Ouvrez list_item_sleep_night.xml.
  2. Dans ImageView, ajoutez une propriété app portant le même nom que l'adaptateur de liaison qui définit l'image. Transmettez la variable sleep, comme indiqué ci-dessous.

    Cette propriété crée la connexion entre la vue et l'objet de liaison via l'adaptateur. Chaque fois que sleepImage est référencé, l'adaptateur adapte les données du SleepNight.
app:sleepImage="@{sleep}"
  1. Procédez de la même façon pour les vues sleep_length et quality_string. Lorsque sleepDurationFormatted ou sleepQualityString sont référencés, les adaptateurs adaptent les données de SleepNight.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
  1. Exécutez votre application. Elle fonctionne exactement comme avant. Les adaptateurs de liaison s'occupent de toutes les tâches de mise en forme et de mise à jour des vues à mesure que les données changent, simplifiant le processus ViewHolder et conférer au code une structure bien meilleure qu'auparavant.

Vous avez affiché la même liste pour les derniers exercices. C'est l'interface Adapter qui vous permet de concevoir votre code de différentes manières. Plus votre code est complexe, plus il est important de bien le concevoir. Dans les applications de production, ces modèles et d'autres sont utilisés avec RecyclerView. Ces modèles sont efficaces, chacun présentant ses avantages. L'option que vous choisissez dépend de ce que vous créez.

Félicitations ! Vous êtes maintenant sur le point de maîtriser RecyclerView sur Android.

Projet Android Studio: RecyclerViewDiffUtilDataBinding

DiffUtil :

  • RecyclerView comporte une classe DiffUtil qui permet de calculer les différences entre deux listes.
  • DiffUtil comporte une classe ItemCallBack que vous étendez pour déterminer la différence entre deux listes.
  • Dans la classe ItemCallback, vous devez remplacer les méthodes areItemsTheSame() et areContentsTheSame().

ListAdapter :

  • Pour bénéficier d'une gestion offerte des listes, vous pouvez utiliser la classe ListAdapter au lieu de RecyclerView.Adapter. Cependant, si vous utilisez ListAdapter, vous devez écrire votre propre adaptateur pour d'autres mises en page. C'est pourquoi cet atelier de programmation vous explique comment procéder.
  • Pour ouvrir le menu d'intent dans Android Studio, placez le curseur sur un élément de code et appuyez sur Alt+Enter (Option+Enter sur un Mac). Ce menu est particulièrement utile pour refactoriser le code et créer des bouchons pour l'implémentation de méthodes. Le menu est sensible au contexte. Vous devez donc placer le curseur exactement pour voir le menu correct.

Liaison de données:

  • Utiliser la liaison de données dans la mise en page de l'élément pour lier les données aux vues.

Adaptateurs de liaison:

  • Vous avez déjà utilisé Transformations pour créer des chaînes de données. Si vous devez lier des données de types différents ou complexes, fournissez des adaptateurs de liaison pour faciliter la liaison de données.
  • Pour déclarer un adaptateur de liaison, définissez une méthode qui utilise un élément et une vue, puis annotez la méthode avec @BindingAdapter. En langage Kotlin, vous pouvez écrire l'adaptateur de liaison en tant que fonction d'extension sur View. Transmettez le nom de la propriété que l'adaptateur adapte. Exemple :
@BindingAdapter("sleepDurationFormatted")
  • Dans la mise en page XML, définissez une propriété app portant le même nom que l'adaptateur de liaison. Transmettez une variable avec les données. Exemple :
.app:sleepDurationFormatted="@{sleep}"

Cours Udacity:

Documentation pour les développeurs Android:

Autres ressources:

Cette section répertorie les devoirs possibles pour les élèves qui effectuent cet atelier de programmation dans le cadre d'un cours animé par un enseignant. C'est à l'enseignant de procéder comme suit:

  • Si nécessaire, rendez-les.
  • Communiquez aux élèves comment rendre leurs devoirs.
  • Notez les devoirs.

Les enseignants peuvent utiliser ces suggestions autant qu'ils le souhaitent, et ils n'ont pas besoin d'attribuer les devoirs de leur choix.

Si vous suivez vous-même cet atelier de programmation, n'hésitez pas à utiliser ces devoirs pour tester vos connaissances.

Répondez à ces questions.

Question 1

Parmi les propositions suivantes, lesquelles sont nécessaires pour utiliser DiffUtil ? Sélectionnez toutes les réponses applicables.

▢ Cela étend la classe ItemCallBack.

▢ Ignorer areItemsTheSame().

▢ Ignorer areContentsTheSame().

▢ Utilisez les liaisons de données pour suivre les différences entre les éléments.

Question 2

Parmi les affirmations suivantes concernant les adaptateurs de liaison, lesquelles sont vraies ?

▢ L'adaptateur est une fonction annotée avec @BindingAdapter.

▢ Grâce à un adaptateur de liaisons, vous pouvez séparer les formats de données du conteneur.

▢ Vous devez utiliser un RecyclerViewAdapter si vous voulez utiliser des adaptateurs de liaison.

▢ Les adaptateurs de liaisons constituent une bonne solution pour transformer des données complexes.

Question 3

Quand devez-vous utiliser Transformations au lieu d'un adaptateur de liaison ? Sélectionnez toutes les réponses applicables.

▢ Vos données sont simples.

▢ Vous formatez une chaîne.

▢ Votre liste est très longue.

ViewHolder Votre vue ne contient qu'une seule vue.

Lancez la leçon suivante: 7.3: GridLayout with RecyclerView