Android Kotlin Fundamentals 07.2: DiffUtil e data binding con RecyclerView

Questo codelab fa parte del corso Android Kotlin Fundamentals. Per ottenere il massimo valore da questo corso, ti consigliamo di seguire le codelab in sequenza. Tutti i codelab del corso sono elencati nella pagina di destinazione dei codelab Android Kotlin Fundamentals.

Introduzione

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

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

Cosa devi già sapere

  • Creazione di un'interfaccia utente di base utilizzando un'attività, frammenti e visualizzazioni.
  • Spostarsi tra i fragment e utilizzare safeArgs per passare i dati tra i fragment.
  • Visualizza modelli, fabbriche di modelli, trasformazioni e LiveData e i relativi osservatori.
  • Come creare un database Room, creare un DAO e definire le entità.
  • Come utilizzare le coroutine per il database e altre attività di lunga durata.
  • Come implementare un RecyclerView di base con un layout Adapter, ViewHolder e degli elementi.

Obiettivi didattici

  • Come utilizzare DiffUtil per aggiornare in modo efficiente un elenco visualizzato da RecyclerView.
  • Come utilizzare il data binding con RecyclerView.
  • Come utilizzare gli adattatori di binding per trasformare i dati.

In questo lab proverai a:

  • Sviluppa l'app TrackMySleepQuality del codelab precedente di questa serie.
  • Aggiorna SleepNightAdapter per aggiornare in modo efficiente l'elenco utilizzando DiffUtil.
  • Implementa il data binding per RecyclerView utilizzando gli adattatori di binding per trasformare i dati.

L'app per il monitoraggio del sonno ha due schermate, rappresentate da frammenti, come mostrato nella figura seguente.

La prima schermata, mostrata a sinistra, ha pulsanti per avviare e interrompere il monitoraggio. La schermata mostra alcuni dati sul sonno dell'utente. Il pulsante Cancella elimina definitivamente tutti i dati raccolti dall'app per l'utente. La seconda schermata, mostrata a destra, serve per selezionare una valutazione della qualità del sonno.

Questa app è progettata per utilizzare un controller UI, ViewModel e LiveData, e un database Room per archiviare i dati sul sonno.

I dati sul sonno vengono visualizzati in un RecyclerView. In questo codelab, creerai la parte DiffUtil e il data binding per RecyclerView. Al termine di questo codelab, la tua app avrà lo stesso aspetto, ma sarà più efficiente e più facile da scalare e gestire.

Puoi continuare a utilizzare l'app SleepTracker del codelab precedente oppure 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. Consulta il diagramma di seguito per un riepilogo dell'utilizzo di RecyclerView con il pattern dell'adattatore per mostrare i dati sul sonno all'utente.

  • A partire dall'input utente, l'app crea un elenco di oggetti SleepNight. Ogni oggetto SleepNight rappresenta una singola notte di sonno, la sua durata e la sua qualità.
  • SleepNightAdapter adatta l'elenco degli oggetti SleepNight in modo che RecyclerView possa utilizzarli e visualizzarli.
  • L'adattatore SleepNightAdapter produce ViewHolders che contengono le visualizzazioni, i dati e i metadati per la visualizzazione riciclata per mostrare i dati.
  • RecyclerView utilizza SleepNightAdapter per determinare quanti elementi visualizzare (getItemCount()). RecyclerView utilizza onCreateViewHolder() e onBindViewHolder() per ottenere i segnaposto della visualizzazione associati ai dati da visualizzare.

Il metodo notifyDataSetChanged() è inefficiente

Per comunicare a RecyclerView che un elemento dell'elenco è stato modificato 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() comunica a RecyclerView che l'intero elenco è potenzialmente non valido. Di conseguenza, RecyclerView esegue il rebinding e il ridisegno di ogni elemento dell'elenco, inclusi quelli non visibili sullo schermo. Si tratta di un sacco di lavoro inutile. Per elenchi grandi o complessi, questa procedura potrebbe richiedere un tempo sufficiente a far sfarfallare o balbettare la visualizzazione mentre l'utente scorre l'elenco.

Per risolvere il problema, puoi comunicare a RecyclerView esattamente cosa è cambiato. RecyclerView può quindi 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 puoi utilizzare funzioni simili per gli elementi aggiunti, rimossi o spostati. Potresti fare tutto manualmente, ma questa attività non sarebbe banale e potrebbe richiedere un bel po' di codice.

Fortunatamente, esiste un modo migliore.

DiffUtil è efficiente e fa il lavoro più impegnativo al posto tuo

RecyclerView ha una classe chiamata DiffUtil che serve per calcolare le differenze tra due elenchi. DiffUtil prende un elenco precedente e uno nuovo e determina le differenze. Trova gli elementi che sono stati aggiunti, rimossi o modificati. Poi utilizza un algoritmo chiamato Eugene W. Myers's difference algorithm per calcolare il numero minimo di modifiche da apportare all'elenco precedente 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, il che è molto più efficiente rispetto al rifacimento dell'intero elenco.

In questa attività, esegui l'upgrade di SleepNightAdapter per utilizzare 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 per SleepNightAdapter, crea una nuova classe di primo livello chiamata SleepNightDiffCallback che estende DiffUtil.ItemCallback. Trasmetti SleepNight come parametro generico.
class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() {
}
  1. Posiziona il cursore sul nome del corso SleepNightDiffCallback.
  2. Premi Alt+Enter (Option+Enter su Mac) e seleziona Implementa membri.
  3. Nella finestra di dialogo che si apre, fai clic con il tasto sinistro del mouse tenendo premuto il tasto Maiusc per selezionare i metodi areItemsTheSame() e areContentsTheSame(), quindi fai clic su Ok.

    Vengono generati stub all'interno di SleepNightDiffCallback per i due metodi, come mostrato di seguito. DiffUtil utilizza questi due metodi per capire come sono cambiati l'elenco e gli elementi.
    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 il 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. In caso contrario, restituisci false. DiffUtil utilizza questo test per rilevare 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(), controlla 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. Le classi Data definiscono automaticamente equals e alcuni altri metodi. Se esistono differenze tra oldItem e newItem, questo codice indica a DiffUtil che l'articolo è stato aggiornato.
override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean {
   return oldItem == newItem
}

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

ListAdapter tiene traccia dell'elenco per te e invia una notifica all'adattatore quando l'elenco viene aggiornato.

Passaggio 1: modifica l'adattatore per estendere ListAdapter

  1. Nel file SleepNightAdapter.kt, modifica la firma della classe di SleepNightAdapter per estendere ListAdapter.
  2. Se richiesto, importa androidx.recyclerview.widget.ListAdapter.
  3. Aggiungi SleepNight come primo argomento a ListAdapter, prima di SleepNightAdapter.ViewHolder.
  4. Aggiungi SleepNightDiffCallback() come parametro al costruttore. ListAdapter utilizzerà questo valore per capire cosa è cambiato nell'elenco. La firma della classe SleepNightAdapter completata dovrebbe avere l'aspetto mostrato di seguito.
class SleepNightAdapter : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) {
  1. All'interno della classe SleepNightAdapter, elimina il campo data, incluso il setter. Non ti serve più perché ListAdapter tiene traccia dell'elenco per te.
  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 submitList() per mantenere aggiornato l'elenco

Il codice deve comunicare a ListAdapter quando è disponibile un elenco modificato. ListAdapter fornisce un metodo chiamato submitList() per comunicare a ListAdapter che è disponibile una nuova versione dell'elenco. Quando viene chiamato questo metodo, ListAdapter confronta il nuovo elenco con quello precedente e rileva gli elementi aggiunti, rimossi, spostati o modificati. A questo punto, ListAdapter aggiorna gli elementi mostrati 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 a adapter.submitList(it). Il codice aggiornato è mostrato di seguito.

sleepTrackerViewModel.nights.observe(viewLifecycleOwner, Observer {
   it?.let {
       adapter.submitList(it)
   }
})
  1. Esegui l'app. Viene eseguita più velocemente, anche se non in modo evidente se l'elenco è piccolo.

In questa attività, utilizzerai la stessa tecnica delle codelab precedenti per configurare il data binding ed eliminerai le chiamate a findViewById().

Passaggio 1: aggiungi il data binding 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 Mac). Si apre il menu degli intenti (il menu "Correzione rapida").
  3. Seleziona Converti in layout di data binding. Il layout viene inserito in <layout> e viene aggiunto un tag <data> all'interno.
  4. Se necessario, scorri di nuovo verso l'alto e, all'interno del tag <data>, dichiara una variabile denominata sleep.
  5. Imposta type come nome completo di SleepNight, com.example.android.trackmysleepquality.database.SleepNight. Il tag <data> completato dovrebbe avere l'aspetto 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, poi seleziona Build > Rebuild Project. Se i problemi persistono, seleziona File > Invalida cache / Riavvia. L'oggetto di binding ListItemSleepNightBinding, insieme al codice correlato, viene aggiunto ai file generati del progetto.

Passaggio 2: gonfia il layout dell'elemento utilizzando il data binding

  1. Apri SleepNightAdapter.kt.
  2. Nella classe 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 aumenti l'oggetto di binding ListItemSleepNightBinding, come mostrato di seguito. Esegui l'importazione necessaria dell'oggetto di binding.
val binding =
ListItemSleepNightBinding.inflate(layoutInflater, parent, false)
  1. Alla fine della funzione, anziché restituire view, restituisci binding.
return ViewHolder(binding)
  1. Per eliminare l'errore, posiziona il cursore sulla parola binding. Premi Alt+Enter (Option+Enter su Mac) per aprire il menu Intenzione.
  1. Seleziona Change parameter 'itemView' type of primary constructor of class 'ViewHolder' to 'ListItemSleepNightBinding'. Viene aggiornato il tipo di parametro della classe ViewHolder.

  1. Scorri verso l'alto fino alla definizione della classe ViewHolder per visualizzare la modifica nella firma. Viene visualizzato un errore per itemView perché hai modificato itemView in binding nel metodo from().

    Nella definizione della classe ViewHolder, fai clic con il tasto destro del mouse su una delle occorrenze di itemView e seleziona Refactor > Rename. Modifica il nome in binding.
  2. Anteponi il parametro del costruttore binding a val per renderlo una proprietà.
  3. Nella chiamata alla classe padre, RecyclerView.ViewHolder, modifica il parametro da binding a binding.root. Devi superare un View e binding.root è la ConstraintLayout principale nel layout dell'elemento.
  4. La dichiarazione della classe completata dovrebbe essere simile al codice riportato di seguito.
class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){

Viene visualizzato anche un errore per le chiamate a findViewById(), che correggerai in un secondo momento.

Passaggio 3: sostituisci findViewById()

Ora puoi aggiornare le proprietà sleepLength, quality e qualityImage per utilizzare l'oggetto binding anziché findViewById().

  1. Modifica le inizializzazioni di sleepLength, qualityString e qualityImage in modo che utilizzino le visualizzazioni 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

Con l'oggetto di binding in posizione, non è più necessario definire le proprietà sleepLength, quality e qualityImage. DataBinding memorizzerà nella cache le ricerche, quindi non è necessario dichiarare queste proprietà.

  1. Fai clic con il tasto destro del mouse sui nomi delle proprietà sleepLength, quality e qualityImage. Seleziona Refactor > Inline o premi Control+Command+N (Option+Command+N su Mac).
  2. Esegui l'app. Potrebbe essere necessario pulire e ricompilare il progetto se contiene errori.

In questa attività, esegui l'upgrade dell'app per utilizzare il data binding con i binding adapter per impostare i dati nelle visualizzazioni.

In un precedente codelab, hai utilizzato la classe Transformations per prendere LiveData e generare stringhe formattate da visualizzare nelle visualizzazioni di testo. Tuttavia, se devi associare tipi diversi o complessi, puoi fornire adattatori di binding per aiutare il data binding a utilizzare questi tipi. Gli adattatori di binding prendono i tuoi dati e li adattano in modo che il data binding possa utilizzarli per associare una visualizzazione, ad esempio testo o un'immagine.

Implementerai tre adattatori di binding, uno per l'immagine di qualità e uno per ogni campo di testo. In sintesi, per dichiarare un adattatore di binding, definisci un metodo che accetta un elemento e una visualizzazione e lo annoti con @BindingAdapter. Nel corpo del metodo, implementa la trasformazione. In Kotlin, puoi scrivere un adattatore di binding come funzione di estensione nella classe di visualizzazione che riceve i dati.

Passaggio 1: crea gli adattatori di binding

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

  1. Apri SleepNightAdapater.kt.
  2. All'interno della classe ViewHolder, trova il metodo bind() e ricorda a cosa serve. Prenderai il codice che calcola i valori per binding.sleepLength, binding.quality e binding.qualityImage e lo utilizzerai all'interno dell'adattatore. Per il momento, lascia il codice così com'è. Lo sposterai 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 sarà il tuo adattatore per calcolare e formattare la durata del sonno.
fun TextView.setSleepDurationFormatted(item: SleepNight) {}
  1. Nel corpo di setSleepDurationFormatted, associa i dati alla visualizzazione come hai fatto in ViewHolder.bind(). Chiama convertDurationToFormatted() e poi imposta text di 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 al data binding questo adattatore di binding, 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 di un oggetto SleepNight. Crea una funzione di estensione chiamata setSleepQualityString() su TextView e trasmetti un SleepNight.
  2. Nel corpo, associa i dati alla visualizzazione come hai fatto in ViewHolder.bind(). Chiama convertNumericQualityToString e imposta 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 binding imposta l'immagine su una visualizzazione immagine. Crea la funzione di 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 ciò che è presente nel metodo bind(), perché ora puoi utilizzare il data binding e i nuovi adattatori per svolgere questo lavoro.
fun bind(item: SleepNight) {
}
  1. All'interno di bind(), assegna la sospensione a item, perché devi comunicare all'oggetto di binding il nuovo SleepNight.
binding.sleep = item
  1. Sotto questa riga, aggiungi binding.executePendingBindings(). Questa chiamata è un'ottimizzazione che chiede all'associazione di dati di eseguire immediatamente tutte le associazioni in attesa. È sempre una buona idea chiamare executePendingBindings() quando utilizzi adattatori di binding in un RecyclerView, perché può velocizzare leggermente il dimensionamento delle visualizzazioni.
 binding.executePendingBindings()

Passaggio 3: aggiungi i binding al layout XML

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

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

Hai visualizzato lo stesso elenco per gli ultimi esercizi. È una scelta progettuale, per mostrarti che l'interfaccia Adapter ti consente di strutturare il codice in molti modi diversi. Più complesso è il codice, più importante diventa progettarlo bene. Nelle app di produzione, questi pattern e altri vengono utilizzati con RecyclerView. Tutti i pattern funzionano e ognuno ha i suoi vantaggi. La scelta dipende da ciò che stai creando.

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

Progetto Android Studio: RecyclerViewDiffUtilDataBinding.

DiffUtil:

  • RecyclerView ha una classe chiamata DiffUtil che serve per calcolare le differenze tra due elenchi.
  • DiffUtil ha una classe chiamata ItemCallBack che estendi per capire la differenza tra due elenchi.
  • Nella classe ItemCallback, devi eseguire l'override dei metodi areItemsTheSame() e areContentsTheSame().

ListAdapter:

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

Associazione di dati:

  • Utilizza il data binding nel layout dell'elemento per associare i dati alle visualizzazioni.

Adattatori per attacchi:

  • In precedenza hai utilizzato Transformations per creare stringhe dai dati. Se devi associare dati di tipi diversi o complessi, fornisci adattatori di binding per consentire al data binding di utilizzarli.
  • Per dichiarare un adattatore di binding, definisci un metodo che accetta un elemento e una visualizzazione e annota il metodo con @BindingAdapter. In Kotlin, puoi scrivere l'adattatore di binding come funzione di estensione su View. Inserisci il nome della proprietà che l'adattatore adatta. Ad esempio:
@BindingAdapter("sleepDurationFormatted")
  • Nel layout XML, imposta una proprietà app con lo stesso nome dell'adattatore di binding. Passa una variabile con i dati. Ad esempio:
.app:sleepDurationFormatted="@{sleep}"

Corsi Udacity:

Documentazione per sviluppatori Android:

Altre risorse:

Questa sezione elenca i possibili compiti a casa per gli studenti che seguono questo codelab nell'ambito di un corso guidato da un insegnante. Spetta all'insegnante:

  • Assegna i compiti, se richiesto.
  • Comunica agli studenti come inviare i compiti.
  • Valuta i compiti a casa.

Gli insegnanti possono utilizzare questi suggerimenti nella misura che ritengono opportuna e sono liberi di assegnare qualsiasi altro compito a casa che ritengono appropriato.

Se stai seguendo questo codelab in autonomia, sentiti libero di utilizzare questi compiti per casa 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 opzioni pertinenti.

▢ Estendi il corso ItemCallBack.

▢ Override areItemsTheSame().

▢ Override areContentsTheSame().

▢ Utilizza il data binding per monitorare le differenze tra gli elementi.

Domanda 2

Quali delle seguenti affermazioni sugli adattatori di binding sono vere?

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

▢ L'utilizzo di un binding adapter consente di separare la formattazione dei dati dal view holder.

▢ Devi utilizzare un RecyclerViewAdapter se vuoi utilizzare gli adattatori di binding.

▢ Gli adattatori di binding sono una buona soluzione quando devi trasformare dati complessi.

Domanda 3

Quando dovresti prendere in considerazione l'utilizzo di Transformations anziché un binding adapter? Seleziona tutte le opzioni pertinenti.

▢ I tuoi dati sono semplici.

▢ Stai formattando una stringa.

▢ Il tuo elenco è molto lungo.

▢ La tua ViewHolder contiene una sola visualizzazione.

Inizia la lezione successiva: 7.3: GridLayout con RecyclerView