Android Kotlin Fundamentals 07.2: DiffUtil e associazione di dati con RecyclerView

Questo codelab fa parte del corso Android Kotlin Fundamentals. Otterrai il massimo valore da questo corso se lavori in sequenza nei codelab. Tutti i codelab del corso sono elencati nella pagina di destinazione di Android Kotlin Fundamentals.

Introduzione

Nel codelab precedente, hai aggiornato l'app TrackMySleepQualità per visualizzare i dati sulla qualità del sonno in un RecyclerView. Le tecniche che hai imparato quando hai creato il tuo primo RecyclerView sono sufficienti per la maggior parte degli RecyclerViews che mostrano elenchi semplici troppo grandi. Tuttavia, esistono diverse tecniche che rendono RecyclerView più efficiente per gli elenchi di grandi dimensioni e che semplificano la manutenzione e l'estensione del codice per elenchi e griglie complessi.

In questo codelab, utilizzi l'app di monitoraggio del sonno del codelab precedente. Scopri un modo più efficace per aggiornare l'elenco dei dati sul sonno e come utilizzare l'associazione di dati con RecyclerView. Se non hai l'app del codelab precedente, puoi scaricare il codice di avvio per questo codelab.

Informazioni importanti

  • Creare un'interfaccia utente di base con attività, frammenti e viste.
  • Spostamento tra frammenti e utilizzo di safeArgs per trasmettere dati tra frammenti.
  • Visualizza modelli, fabbriche di modelli, trasformazioni e LiveData e i loro osservatori.
  • Come creare un database Room, creare un DAO e definire le entità.
  • Come utilizzare le coroutine per i database e altre attività di lunga durata.
  • Come implementare un elemento RecyclerView di base con un layout Adapter, ViewHolder e un elemento.

Obiettivi didattici

  • Come utilizzare DiffUtil per aggiornare in modo efficiente un elenco visualizzato da RecyclerView.
  • Come utilizzare l'associazione di dati con RecyclerView.
  • Come usare gli adattatori vincolanti per trasformare i dati.

In questo lab proverai a:

  • Crea sull'app TrackMySleepQualità del codelab precedente di questa serie.
  • Aggiorna SleepNightAdapter per aggiornare l'elenco in modo efficiente utilizzando DiffUtil.
  • Implementa l'associazione di dati per RecyclerView utilizzando adattatori di associazione per trasformare i dati.

L'app di monitoraggio del sonno è composta da due schermate, rappresentate da frammenti, come mostrato nella figura che segue.

La prima schermata, mostrata a sinistra, contiene pulsanti per avviare e interrompere il monitoraggio. Sullo schermo sono visualizzati alcuni dati del sonno dell'utente. Il pulsante Cancella elimina definitivamente tutti i dati raccolti dall'app per l'utente. La seconda schermata, mostrata a destra, consente di selezionare una valutazione della qualità del sonno.

Questa architettura è progettata per utilizzare un controller dell'interfaccia utente, ViewModel e LiveData, e un database Room per conservare i dati relativi al sonno.

I dati relativi al sonno vengono mostrati in un elemento RecyclerView. In questo codelab, crei la parte DiffUtil e l'associazione dei dati per RecyclerView. Dopo questo codelab, l'app avrà lo stesso aspetto, ma sarà più efficiente e facile da scalare e gestire.

Puoi continuare a utilizzare l'app SleepTracker dal codelab precedente oppure puoi scaricare l'app RecyclerViewDiffUtilDataBinding-Starter da GitHub.

  1. Se necessario, scarica l'app RecyclerViewDiffUtilDataBinding-Starter da GitHub e apri il progetto in Android Studio.
  2. Esegui l'app.
  3. Apri il file SleepNightAdapter.kt.
  4. Esamina il codice per acquisire familiarità con la struttura dell'app. Fai riferimento al diagramma seguente per un riepilogo dell'utilizzo di RecyclerView con il modello di adattatore per mostrare i dati sul sonno all'utente.

  • In base all'input dell'utente, l'app crea un elenco di oggetti SleepNight. Ogni oggetto SleepNight rappresenta una singola notte di sonno, la sua durata e la qualità.
  • SleepNightAdapter adatta l'elenco di oggetti SleepNight a un oggetto che RecyclerView può utilizzare e visualizzare.
  • L'adattatore SleepNightAdapter produce ViewHolders che contengono le viste, i dati e le meta informazioni per la visualizzazione del riciclo che consentono di visualizzare i dati.
  • RecyclerView utilizza SleepNightAdapter per determinare il numero di elementi da visualizzare (getItemCount()). RecyclerView utilizza onCreateViewHolder() e onBindViewHolder() per fare in modo che i proprietari delle visualizzazioni limitino ai dati da visualizzare.

Il metodo notificationDataSetChanged() non è efficiente

Per indicare a RecyclerView che un elemento nell'elenco è cambiato e deve essere aggiornato, il codice corrente chiama notifyDataSetChanged() in SleepNightAdapter, come mostrato di seguito.

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

Tuttavia, notifyDataSetChanged() indica a RecyclerView che l'intero elenco non è potenzialmente valido. Di conseguenza, RecyclerView associa e trascina nuovamente tutti gli elementi nell'elenco, inclusi quelli non visibili sullo schermo. Si tratta di una quantità di lavoro inutile. Per elenchi di grandi dimensioni o complessi, questo processo potrebbe richiedere un tempo sufficiente da consentire lo sfarfallio o lo sfarfallio del display mentre l'utente scorre l'elenco.

Per risolvere questo problema, puoi indicare a RecyclerView esattamente cosa è cambiato. RecyclerView può poi aggiornare solo le visualizzazioni che sono cambiate sullo schermo.

RecyclerView dispone di un'API avanzata per l'aggiornamento di un singolo elemento. Puoi utilizzare notifyItemChanged() per comunicare a RecyclerView che un elemento è stato modificato e utilizzare funzioni simili per gli elementi che vengono aggiunti, rimossi o spostati. Si potrebbe fare tutto manualmente, ma l'attività non sarebbe banale e potrebbe richiedere molto codice.

Fortunatamente, c'è un modo migliore.

DiffUtil è efficace e fa il massimo per te

RecyclerView è presente in una classe chiamata DiffUtil, che serve per calcolare le differenze tra due elenchi. DiffUtil prende un vecchio elenco, uno nuovo e sceglie cosa cambia. Trova gli elementi che sono stati aggiunti, rimossi o modificati. Quindi utilizza un algoritmo chiamato Eugene W. L'algoritmo di differenza di Myers per determinare il numero minimo di modifiche da apportare al vecchio elenco per produrre il nuovo elenco.

Una volta che DiffUtil ha capito cosa è cambiato, RecyclerView può utilizzare queste informazioni per aggiornare solo gli elementi che sono stati modificati, aggiunti, rimossi o spostati, un'operazione molto più efficiente rispetto al ripristino dell'intero elenco.

In questa attività, esegui l'upgrade del SleepNightAdapter in modo che utilizzi DiffUtil per ottimizzare RecyclerView per le modifiche ai dati.

Passaggio 1: implementa SleepNightDiffCallback

Per utilizzare la funzionalità della classe DiffUtil, estendi DiffUtil.ItemCallback.

  1. Apri SleepNightAdapter.kt.
  2. Sotto la definizione completa della classe SleepNightAdapter, crea una nuova classe di primo livello denominata SleepNightDiffCallback che estende DiffUtil.ItemCallback. Passaggio SleepNight come parametro generico.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
  1. Inserisci il cursore nel nome della classe SleepNightDiffCallback.
  2. Premi Alt+Enter (Option+Enter su Mac) e seleziona Implementa membri.
  3. Nella finestra di dialogo visualizzata, fai clic con il tasto sinistro del mouse per selezionare i metodi areItemsTheSame() e areContentsTheSame(), quindi fai clic su OK.

    In questo modo generi le stub all'interno di SleepNightDiffCallback per i due metodi, come mostrato di seguito. DiffUtil utilizza questi due metodi per capire come sono cambiati gli articoli e l'elenco.
    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. All'interno di areItemsTheSame(), sostituisci TODO con un codice che verifica se i due elementi SleepNight passati, oldItem e newItem, sono uguali. Se gli articoli hanno lo stesso nightId, sono lo stesso articolo, quindi restituisci true. Altrimenti, restituisci false. DiffUtil utilizza questo test per scoprire se un elemento è stato aggiunto, rimosso o spostato.
override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem.nightId == newItem.nightId
}
  1. All'interno di areContentsTheSame(), verifica se oldItem e newItem contengono gli stessi dati, ovvero se sono uguali. Questo controllo di uguaglianza controllerà tutti i campi, perché SleepNight è una classe di dati. I corsi Data definiscono automaticamente equals e alcuni altri metodi. In caso di differenze tra oldItem e newItem, questo codice indica a DiffUtil che l'elemento è stato aggiornato.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem == newItem
}

È un motivo comune per utilizzare un RecyclerView per visualizzare un elenco che cambia. RecyclerView fornisce una classe di adattatori, ListAdapter, che ti aiuta a creare un adattatore RecyclerView supportato da un elenco.

ListAdapter monitora l'elenco al posto tuo e invia una notifica all'adattatore quando viene aggiornata.

Passaggio 1: cambia l'adattatore per estendere ListAdapter

  1. Nel file SleepNightAdapter.kt, modifica la firma del corso per SleepNightAdapter in modo da estendere ListAdapter.
  2. Se richiesto, importa androidx.recyclerview.widget.ListAdapter.
  3. Aggiungi SleepNight come primo argomento per ListAdapter, prima di SleepNightAdapter.ViewHolder.
  4. Aggiungi SleepNightDiffCallback() come parametro al costruttore. ListAdapter lo userà per capire cosa è cambiato nell'elenco. La firma del corso, che hai completato in SleepNightAdapter, dovrebbe essere visibile come mostrato di seguito.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. All'interno del corso SleepNightAdapter, elimina il campo data, compreso il setter. Non ne hai più bisogno, perché ListAdapter tiene traccia della tua lista.
  2. Elimina l'override di getItemCount(), perché ListAdapter implementa questo metodo per te.
  3. Per eliminare l'errore in onBindViewHolder(), modifica la variabile item. Anziché utilizzare data per ottenere un item, chiama il metodo getItem(position) fornito da ListAdapter.
val item = getItem(position)

Passaggio 2: utilizza sendList() per mantenere aggiornato l'elenco

Il codice deve comunicare al ListAdapter quando è disponibile un elenco modificato. ListAdapter fornisce un metodo chiamato submitList() per comunicare a ListAdapter che è disponibile una nuova versione dell'elenco. Quando questo metodo viene chiamato, ListAdapter suddivide il nuovo elenco rispetto a quello precedente e rileva gli elementi aggiunti, rimossi, spostati o modificati. Dopodiché ListAdapter aggiorna gli elementi visualizzati da RecyclerView.

  1. Apri SleepTrackerFragment.kt.
  2. In onCreateView(), nell'osservatore su sleepTrackerViewModel, trova l'errore in cui viene fatto riferimento alla variabile data che hai eliminato.
  3. Sostituisci adapter.data = it con una chiamata al numero adapter.submitList(it). Il codice aggiornato è riportato di seguito.

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.submitList(it)
   }
})
  1. Esegui la tua app. L'app viene eseguita più velocemente, forse non in modo evidente se l'elenco è ridotto.

In questa attività utilizzerai la stessa tecnica dei codelab precedenti per configurare l'associazione di dati ed elimini le chiamate a findViewById().

Passaggio 1: aggiungi l'associazione di dati al file di layout

  1. Apri il file di layout list_item_sleep_night.xml nella scheda Testo.
  2. Posiziona il cursore sul tag ConstraintLayout e premi Alt+Enter (Option+Enter su un Mac). Viene visualizzato il menu dell'intent (il menu "Correzione rapida").
  3. Seleziona Converti in layout di associazione di dati. Aggrega il layout in <layout> e aggiunge un tag <data> all'interno.
  4. Se necessario, scorri fino in cima e all'interno del tag <data> dichiara una variabile denominata sleep.
  5. Imposta il suo type come nome completo di SleepNight, com.example.android.trackmysleepquality.database.SleepNight. Il tag <data> dovrebbe essere simile a quello mostrato di seguito.
   <data>
        <variable
            name="sleep"
            type="com.example.android.trackmysleepquality.database.SleepNight"/>
    </data>
  1. Per forzare la creazione dell'oggetto Binding, seleziona Build > Clean Project, quindi seleziona Build > Rebuild Project. Se i problemi persistono, seleziona File > Invalid Invalid Caches / Restart (File non validi/riavvia la cache). L'oggetto di associazione ListItemSleepNightBinding, insieme al codice correlato, viene aggiunto ai file generati del progetto.

Passaggio 2: gonfia il layout degli elementi utilizzando l'associazione di dati

  1. Apri SleepNightAdapter.kt.
  2. Nel corso ViewHolder, trova il metodo from().
  3. Elimina la dichiarazione della variabile view.

Codice da eliminare:

val view = layoutInflater
       .inflate(R.layout.list_item_sleep_night, parent, false)
  1. Dove si trovava la variabile view, definisci una nuova variabile chiamata binding che gonfia l'oggetto binding ListItemSleepNightBinding, come mostrato di seguito. Esegui l'importazione necessaria dell'oggetto binding.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
  1. Alla fine della funzione, invece di restituire view, restituisci binding.
return ViewHolder(binding)
  1. Per eliminare l'errore, posiziona il cursore sulla parola binding. Premi Alt+Enter (Option+Enter su un Mac) per aprire il menu dell'intent.
  1. Seleziona Cambia il parametro 'itemView' tipo di costruttore principale di classe 'Viewholder' a 'ListItemSleepNightBinding'. Viene aggiornato il tipo di parametro della classe ViewHolder.

  1. Scorri fino alla definizione del corso della ViewHolder per vedere la modifica nella firma. Vedi un errore per itemView, perché hai modificato itemView in binding nel metodo from().

    Nella definizione della classe ViewHolder, fai clic con il pulsante destro del mouse su una delle occorrenze di itemView e seleziona Refactoring > Rinomina. Cambia il nome in binding.
  2. Fai precedere il parametro costruttore binding da val per impostarlo come proprietà.
  3. Nella chiamata alla classe principale, RecyclerView.ViewHolder, modifica il parametro da binding a binding.root. Devi superare un View e binding.root è l'elemento principale ConstraintLayout nel layout dell'elemento.
  4. La dichiarazione di classe completata deve avere il seguente codice.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){

Inoltre, vedi un errore per le chiamate al numero findViewById() e lo correggi dopo.

Passaggio 3: sostituisci FindViewById()

Ora puoi aggiornare le proprietà sleepLength, quality e qualityImage in modo che utilizzino l'oggetto binding anziché findViewById().

  1. Modifica le inizializzazioni di sleepLength, qualityString e qualityImage per utilizzare le viste dell'oggetto binding, come mostrato di seguito. Dopodiché, il codice non dovrebbe più mostrare errori.
val sleepLength: TextView = binding.sleepLength
val quality: TextView = binding.qualityString
val qualityImage: ImageView = binding.qualityImage

Una volta impostato l'oggetto associazione, non è più necessario definire le proprietà sleepLength, quality e qualityImage. DataBinding memorizza le query nella cache, quindi non è necessario dichiarare queste proprietà.

  1. Fai clic con il pulsante destro del mouse sui nomi delle proprietà sleepLength, quality e qualityImage. Seleziona Refactor & &t; Inline o premi Control+Command+N (Option+Command+N su un Mac).
  2. Esegui l'app. In caso di errori potrebbe essere necessario pulire e ricreare il progetto.

In questa attività eseguirai l'upgrade dell'app in modo che utilizzi l'associazione di dati con gli adattatori di associazione per impostare i dati nelle viste.

In un codelab precedente, hai utilizzato la classe Transformations per acquisire LiveData e generare stringhe formattate da visualizzare nelle visualizzazioni di testo. Tuttavia, se devi associare diversi tipi o tipi complessi, puoi fornire adattatori di associazione per consentire l'associazione di dati con tali tipi. Gli adattatori di associazione sono adattatori che prendono i tuoi dati e li adattano in qualcosa che l'associazione di dati può utilizzare per associare una visualizzazione, come un testo o un'immagine.

Stai implementando tre adattatori di associazione, uno per l'immagine di qualità e uno per ogni campo di testo. In breve, per dichiarare un adattatore di associazione, devi definire un metodo che prende un elemento e una vista e annotarlo con @BindingAdapter. Nel corpo del metodo devi implementare la trasformazione. In Kotlin puoi scrivere un adattatore di associazione come funzione di estensione nella classe di visualizzazione che riceve i dati.

Passaggio 1: crea gli adattatori di associazione

Tieni presente che dovrai importare un certo numero di corsi nel passaggio e non verranno richiamati individualmente.

  1. Apri SleepNightAdapater.kt.
  2. All'interno del corso ViewHolder, trova il metodo bind() e ricordati come funziona. Prenderai il codice che calcola i valori di binding.sleepLength, binding.quality e binding.qualityImage e lo utilizzerai invece nell'adattatore. Per ora, non modificare il codice. Potrai spostarlo in un passaggio successivo.
  3. Nel pacchetto sleeptracker, crea e apri un file denominato BindingUtils.kt.
  4. Dichiara una funzione di estensione su TextView, chiamata setSleepDurationFormatted, e passa un SleepNight. Questa funzione consente di calcolare e formattare la durata del sonno.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
  1. Nel corpo di setSleepDurationFormatted, associa i dati alla vista come hai fatto in ViewHolder.bind(). Richiama convertDurationToFormatted(), quindi imposta text per TextView sul testo formattato. Poiché si tratta di una funzione di estensione su TextView, puoi accedere direttamente alla proprietà text.
text = convertDurationToFormatted(item.startTimeMilli, item.endTimeMilli, context.resources)
  1. Per comunicare l'associazione dei dati per questo adattatore di associazione, annota la funzione con @BindingAdapter.
  2. Questa funzione è l'adattatore per l'attributo sleepDurationFormatted, quindi passa sleepDurationFormatted come argomento a @BindingAdapter.
@BindingAdapter("sleepDurationFormatted")
  1. Il secondo adattatore imposta la qualità del sonno in base al valore in un oggetto SleepNight. Crea una funzione di estensione chiamata setSleepQualityString() il giorno TextView e trasmetti un SleepNight.
  2. Nel corpo associa i dati alla vista come in ViewHolder.bind(). Chiama convertNumericQualityToString e imposta il text.
  3. Annota la funzione con @BindingAdapter("sleepQualityString").
@BindingAdapter("sleepQualityString")
fun TextView.setSleepQualityString(item: SleepNight) {
   text = convertNumericQualityToString(item.sleepQuality, context.resources)
}
  1. Il terzo adattatore di associazione imposta l'immagine in una visualizzazione immagine. Crea la funzione estensione su ImageView, chiama setSleepImage e utilizza il codice di ViewHolder.bind(), come mostrato di seguito.
@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
   })
}

Passaggio 2: aggiorna SleepNightAdapter

  1. Apri SleepNightAdapter.kt.
  2. Elimina tutto nel metodo bind() perché ora puoi utilizzare l'associazione di dati e i tuoi nuovi adattatori per eseguire questa operazione.
fun bind(item: SleepNight) {
}
  1. All'interno di bind(), assegna il sonno a item, perché devi informare l'oggetto vincolante del tuo nuovo dispositivo SleepNight.
binding.sleep = item
  1. Sotto questa riga, aggiungi binding.executePendingBindings(). Questa chiamata è un'ottimizzazione che chiede all'associazione di dati di eseguire immediatamente le associazioni in attesa. È sempre opportuno chiamare executePendingBindings() quando utilizzi gli adattatori vincolanti in un RecyclerView, perché può velocizzare leggermente le dimensioni delle viste.
 binding.executePendingBindings()

Passaggio 3: aggiungi le associazioni al layout XML

  1. Apri list_item_sleep_night.xml.
  2. In ImageView, aggiungi una proprietà app con lo stesso nome dell'adattatore di associazione che imposta l'immagine. Passa la variabile sleep, come mostrato di seguito.

    Questa proprietà crea il collegamento tra la vista e l'oggetto binding tramite l'adattatore. Ogni volta che viene fatto riferimento a sleepImage, l'adattatore adatta i dati di SleepNight.
app:sleepImage="@{sleep}"
  1. Esegui le stesse azioni per le visualizzazioni di testo sleep_length e quality_string. Quando viene fatto riferimento a sleepDurationFormatted o sleepQualityString, gli adattatori adattano i dati di SleepNight.
app:sleepDurationFormatted="@{sleep}"
app:sleepQualityString="@{sleep}"
  1. Esegui la tua app. Funziona esattamente come prima. Gli adattatori vincolanti si occupano di tutto il lavoro di formattazione e aggiornamento delle viste ogni volta che cambiano i dati, semplificando ViewHolder e fornendo al codice una struttura molto migliore rispetto a prima.

Hai visualizzato lo stesso elenco per gli ultimi allenamenti. È progettato per mostrarti che l'interfaccia di Adapter ti consente di progettare il codice in molti modi diversi. Più complesso è il codice, più importante diventa progettarlo correttamente. Nelle app in produzione, questi pattern e altri vengono utilizzati con RecyclerView. I pattern funzionano bene e ognuno ha i suoi vantaggi. La scelta dipende dall'edificio.

Complimenti! A questo punto sei sulla buona strada per padroneggiare RecyclerView su Android.

Progetto Android Studio: RecyclerViewDiffUtilDataBinding.

DiffUtil:

  • RecyclerView è presente in una classe chiamata DiffUtil, che serve per calcolare le differenze tra due elenchi.
  • DiffUtil è presente una classe chiamata ItemCallBack per capire la differenza tra i due elenchi.
  • Nel corso ItemCallback, devi sostituire i metodi areItemsTheSame() e areContentsTheSame().

ListAdapter:

  • Per ricevere senza costi la gestione degli elenchi, puoi utilizzare la classe ListAdapter anziché RecyclerView.Adapter. Tuttavia, se utilizzi ListAdapter devi scrivere il tuo adattatore per altri layout ed è per questo che questo codelab ti spiega come farlo.
  • Per aprire il menu delle intenzioni in Android Studio, posiziona il cursore su un elemento del codice e premi Alt+Enter (Option+Enter su un Mac). Questo menu è particolarmente utile per il refactoring del codice e per la creazione di stub per l'implementazione dei metodi. Il menu è sensibile al contesto, quindi devi posizionare il cursore esattamente per trovare il menu corretto.

Associazione di dati:

  • Utilizza l'associazione di dati nel layout degli elementi per associare i dati alle viste.

Adattatori per rilegatura:

  • In precedenza hai utilizzato Transformations per creare stringhe di dati. Se devi associare dati di tipi diversi o complessi, fornisci gli adattatori vincolanti per utilizzarli.
  • Per dichiarare un adattatore di associazione, definisci un metodo che utilizzi un elemento e una vista e annota il metodo con @BindingAdapter. In Kotlin puoi scrivere l'adattatore per le associazioni come funzione di estensione in View. Inserisci il nome della proprietà adattata dall'adattatore. Ad esempio:
@BindingAdapter("sleepDurationFormatted")
  • Nel layout XML, imposta una proprietà app con lo stesso nome dell'adattatore di associazione. Trasmetti una variabile con i dati. Ad esempio:
.app:sleepDurationFormatted="@{sleep}"

Corsi Udacity:

Documentazione per gli sviluppatori Android:

Altre risorse:

In questa sezione sono elencati i possibili compiti per gli studenti che lavorano attraverso questo codelab nell'ambito di un corso tenuto da un insegnante. Spetta all'insegnante fare quanto segue:

  • Assegna i compiti, se necessario.
  • Comunica agli studenti come inviare compiti.
  • Valuta i compiti.

Gli insegnanti possono utilizzare i suggerimenti solo quanto e come vogliono e dovrebbero assegnare i compiti che ritengono appropriati.

Se stai lavorando da solo a questo codelab, puoi utilizzare questi compiti per mettere alla prova le tue conoscenze.

Rispondi a queste domande

Domanda 1

Quali dei seguenti elementi sono necessari per utilizzare DiffUtil? Seleziona tutte le risposte pertinenti.

▢ Estendi il corso ItemCallBack.

▢ Sostituisci areItemsTheSame().

▢ Sostituisci areContentsTheSame().

▢ Utilizza l'associazione di dati per tenere traccia delle differenze tra gli articoli.

Domanda 2

Quali delle seguenti affermazioni relative agli adattatori sono vere?

▢ Un adattatore di associazione è una funzione annotata con @BindingAdapter.

▢ L'utilizzo di un adattatore di associazione ti consente di separare la formattazione dei dati da quella del titolare della vista.

▢ Devi utilizzare una RecyclerViewAdapter se vuoi usare adattatori vincolanti.

▢ Gli adattatori sono un'ottima soluzione quando devi trasformare dati complessi.

Domanda 3

Quando dovresti utilizzare Transformations invece di un adattatore di associazione? Seleziona tutte le risposte pertinenti.

▢: i dati sono semplici.

▢ Stai formattando una stringa.

▢ Il tuo elenco è molto lungo.

ViewHolder contiene una sola vista.

Inizia la lezione successiva: 7.3: GridLayout with RecyclerView