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 utilizzato un elemento ViewModel
nell'app GuessTheWord per consentire ai dati dell'app di sopravvivere alle modifiche della configurazione del dispositivo. In questo codelab, imparerai a integrare LiveData
con i dati delle classi ViewModel
. LiveData
, che è uno dei componenti dell'architettura Android, ti consente di creare oggetti di dati che avvisano le viste quando cambia il database sottostante.
Per utilizzare la classe LiveData
, devi configurare"osservatori", ad esempio attività o frammenti, che osservano le modifiche nei dati dell'app. LiveData
è in grado di rilevare il ciclo di vita, pertanto aggiorna solo gli utenti che osservano i componenti dell'app che si trovano in uno stato di ciclo di vita attivo.
Informazioni importanti
- Come creare app Android di base in Kotlin.
- Come navigare tra le destinazioni della tua app.
- Ciclo di vita di attività e frammenti.
- Come utilizzare gli oggetti
ViewModel
nella tua app - Come creare oggetti
ViewModel
utilizzando l'interfaccia diViewModelProvider.Factory
.
Obiettivi didattici
- Perché gli oggetti
LiveData
sono utili. - Come aggiungere
LiveData
ai dati archiviati in unViewModel
. - Quando e come utilizzare
MutableLiveData
. - Come aggiungere metodi di osservazione per osservare le modifiche nel
LiveData.
- Come incapsulare
LiveData
utilizzando una proprietà di supporto. - Come comunicare tra un controller UI e il
ViewModel
corrispondente.
In questo lab proverai a:
- Usa
LiveData
per la parola e il punteggio nell'app GuessTheWord. - Aggiungi osservatori che rilevano la modifica della parola o del punteggio.
- Aggiornare le visualizzazioni di testo che mostrano i valori modificati.
- Utilizza il pattern Osservatore
LiveData
per aggiungere un evento completato dal gioco. - Implementa il pulsante Riproduci di nuovo.
Nei codelab della Lezione 5, sviluppi l'app GuessTheWord, iniziando con il codice di avvio. GuessTheWord è un gioco in stile charade per giocatori, in cui i giocatori collaborano per raggiungere il punteggio più alto possibile.
Il primo giocatore controlla le parole nell'app e le reagisce a turno, assicurandoti di non mostrare la parola al secondo giocatore. Il secondo giocatore prova a indovinare la parola.
Per giocare, il primo giocatore apre l'app sul dispositivo e vede una parola, ad esempio "chitarra", come mostrato nello screenshot di seguito.
Il primo giocatore pronuncia la parola, facendo attenzione a non pronunciare la parola stessa.
- Quando il secondo giocatore indovina la parola correttamente, il primo pulsante preme il pulsante OK, che aumenta il conteggio di uno e mostra la parola successiva.
- Se il secondo giocatore non riesce a indovinare la parola, il primo giocatore preme il pulsante Ignora: in questo modo il numero viene ridotto di uno e passa alla parola successiva.
- Per terminare il gioco, premi il pulsante Termina gioco. Questa funzionalità non è presente nel codice di avvio del primo codelab della serie.
In questo codelab, puoi migliorare l'app GuessTheWord aggiungendo un evento che termina il gioco quando l'utente scorre tutte le parole dell'app. Aggiungi anche un pulsante Gioca di nuovo nel frammento del punteggio, in modo che l'utente possa giocare di nuovo.
Schermata del titolo |
Schermata di gioco |
Schermata punteggio |
In questa attività, troverai ed eseguirai il tuo codice di avvio per questo codelab. Puoi usare come codice di avvio l'app GuessTheWord che hai creato nel codelab precedente oppure puoi scaricare un'app iniziale.
- (Facoltativo) Se non utilizzi il codice del codelab precedente, scarica il codice di avvio per questo codelab. Decomprimi il codice e apri il progetto in Android Studio.
- Esegui l'app e gioca.
- Tieni presente che il pulsante Ignora mostra la parola successiva e riduce il punteggio di uno, mentre il pulsante OK mostra la parola successiva e aumenta il punteggio di uno. Il pulsante Termina gioco consente di terminare il gioco.
LiveData
è una classe di dati osservabili che tiene conto del ciclo di vita. Ad esempio, puoi aggregare un LiveData
al punteggio attuale nell'app GuessTheWord. In questo codelab, puoi conoscere varie caratteristiche di LiveData
:
LiveData
è osservabile, il che significa che un osservatore riceve una notifica quando i dati contenuti nell'oggettoLiveData
cambiano.LiveData
contiene dati;LiveData
è un wrapper utilizzabile con qualsiasi datoLiveData
è sensibile al ciclo di vita, il che significa che aggiorna solo gli osservatori che si trovano in uno stato di ciclo di vita attivo, comeSTARTED
oRESUMED
.
In questa attività imparerai a includere qualsiasi tipo di dati negli oggetti LiveData
convertendo il punteggio corrente e i dati delle parole correnti in GameViewModel
in LiveData
. In un'attività successiva, aggiungi un osservatore a questi oggetti LiveData
e scopri come osservare LiveData
.
Passaggio 1. Modifica il punteggio e la parola per utilizzare LiveData
- Nel pacchetto
screens/game
, apri il fileGameViewModel
. - Cambia il tipo di variabile
score
eword
inMutableLiveData
.MutableLiveData
è unLiveData
di cui è possibile modificare il valore.MutableLiveData
è una classe generica, quindi devi specificare il tipo di dati che contiene.
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()
- In
GameViewModel
, all'interno del bloccoinit
, inizializzascore
eword
. Per modificare il valore di una variabileLiveData
, devi utilizzare il metodosetValue()
. In Kotlin puoi chiamaresetValue()
utilizzando la proprietàvalue
.
init {
word.value = ""
score.value = 0
...
}
Passaggio 2: aggiorna il riferimento all'oggetto LiveData
Le variabili score
e word
sono ora di tipo LiveData
. In questo passaggio, modificherai i riferimenti a queste variabili utilizzando la proprietà value
.
- In
GameViewModel
, nel metodoonSkip()
, modificascore
inscore.value
. Nota l'errorescore
che potrebbe essere relativo anull
. Ora devi correggere questo errore. - Per risolvere l'errore, aggiungi un controllo
null
ascore.value
inonSkip()
. Quindi chiama la funzioneminus()
suscore
, che esegue la sottrazione connull
-safety.
fun onSkip() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.minus(1)
}
nextWord()
}
- Aggiorna il metodo
onCorrect()
nello stesso modo: aggiungi un controllonull
alla variabilescore
e utilizza la funzioneplus()
.
fun onCorrect() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.plus(1)
}
nextWord()
}
- In
GameViewModel
, all'interno del metodonextWord()
, modifica il riferimentoword
inword
.
value
.
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
word.value = wordList.removeAt(0)
}
}
- In
GameFragment
, all'interno del metodoupdateWordText()
, modifica il riferimento inviewModel
.word
inviewModel
.
word
.
value.
/** Methods for updating the UI **/
private fun updateWordText() {
binding.wordText.text = viewModel.word.value
}
- In
GameFragment
, all'interno del metodoupdateScoreText()
, cambia il riferimento inviewModel
.score
inviewModel
.
score
.
value.
private fun updateScoreText() {
binding.scoreText.text = viewModel.score.value.toString()
}
- In
GameFragment
, all'interno del metodogameFinished()
, modifica il riferimento inviewModel
.score
inviewModel
.
score
.
value
. Aggiungi il controllo di sicurezzanull
obbligatorio.
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
val action = GameFragmentDirections.actionGameToScore()
action.score = viewModel.score.value?:0
NavHostFragment.findNavController(this).navigate(action)
}
- Assicurati che il codice non contenga errori. Compila ed esegui la tua app. La funzionalità dell'app deve essere invariata.
Questa attività è strettamente correlata all'attività precedente, in cui hai convertito i dati del punteggio e delle parole in oggetti LiveData
. In questa attività, dovrai collegare oggetti Observer
a tali oggetti LiveData
.
- In
GameFragment,
all'interno del metodoonCreateView()
, collega un oggettoObserver
all'oggettoLiveData
per il punteggio attuale,viewModel.score
. Usa il metodoobserve()
e inserisci il codice dopo l'inizializzazione diviewModel
. Utilizza un'espressione lambda per semplificare il codice. Un'espressione lambda è una funzione anonima che non viene dichiarata, ma che viene trasmessa immediatamente come espressione.
viewModel.score.observe(this, Observer { newScore ->
})
Risolvi il riferimento a Observer
. Per farlo, fai clic su Observer
, premi Alt+Enter
(Option+Enter
su un Mac) e importa androidx.lifecycle.Observer
.
- L'osservatore che hai appena creato riceve un evento quando i dati contenuti nell'oggetto
LiveData
osservato cambiano. All'interno di chi osserva la classifica, aggiorna il punteggioTextView
con il nuovo punteggio.
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- Allega un oggetto
Observer
all'oggetto parolaLiveData
corrente. Esegui la stessa operazione con l'aggiunta di un oggettoObserver
al punteggio corrente.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
Quando il valore di score
o di word
cambia, i valori di score
o word
visualizzati sullo schermo ora vengono aggiornati automaticamente.
- In
GameFragment
, elimina i metodiupdateWordText()
eupdateScoreText()
, nonché tutti i riferimenti a questi metodi. Non ne hai più bisogno, perché le visualizzazioni del testo vengono aggiornate con i metodi osservatoreLiveData
. - Esegui la tua app. L'app di gioco dovrebbe funzionare come prima, ma ora utilizza
LiveData
eLiveData
osservatori.
L'incapsulamento è un modo per limitare l'accesso diretto ad alcuni campi dell'oggetto. Quando incapsula un oggetto, esponi un insieme di metodi pubblici che modificano i campi interni privati. Utilizzando l'incapsulamento, puoi controllare il modo in cui le altre classi manipolano questi campi interni.
Nel codice attuale, qualsiasi classe esterna può modificare le variabili score
e word
utilizzando la proprietà value
, ad esempio utilizzando viewModel.score.value
. Indipendentemente dall'app che stai sviluppando in questo codelab, tieni presente che in un'app di produzione vuoi il controllo dei dati negli oggetti ViewModel
.
Solo ViewModel
può modificare i dati nella tua app. Tuttavia, i controller dell'interfaccia utente devono leggere i dati, di conseguenza i campi dei dati non possono essere completamente privati. Per incapsulare i dati dell'app, si utilizzano gli oggetti MutableLiveData
e LiveData
.
MutableLiveData
rispetto a LiveData
:
- I dati in un oggetto
MutableLiveData
possono essere modificati, come indica il nome. All'interno diViewModel
, i dati dovrebbero essere modificabili, pertanto utilizzanoMutableLiveData
. - I dati in un oggetto
LiveData
possono essere letti, ma non modificati. Al di fuori diViewModel
, i dati devono essere leggibili, ma non modificabili, quindi devono essere esposti comeLiveData
.
Per mettere in pratica questa strategia, utilizza una proprietà di supporto Kotlin. Una proprietà di supporto consente di restituire un elemento da un getter diverso dall'oggetto esatto. In questa attività implementerai una proprietà di supporto per gli oggetti score
e word
nell'app GuessTheWord.
Aggiungi una proprietà di supporto al punteggio e alla parola
- In
GameViewModel
, imposta l'oggettoscore
corrente comeprivate
. - Per seguire la convenzione di denominazione utilizzata nelle proprietà di supporto, cambia
score
in_score
. Ora la proprietà_score
è la versione modificabile del punteggio del gioco da utilizzare internamente. - Crea una versione pubblica di tipo
LiveData
, denominatascore
.
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
- Viene visualizzato un errore di inizializzazione. Questo errore si verifica perché all'interno di
GameFragment
,score
è un riferimento diLiveData
escore
non può più accedere al setter. Per scoprire di più su getter e setter in Kotlin, vedi Getter e setter.
Per risolvere l'errore, esegui l'override del metodoget()
per l'oggettoscore
inGameViewModel
e restituisci la proprietà di supporto,_score
.
val score: LiveData<Int>
get() = _score
- In
GameViewModel
, modifica i riferimenti discore
alla sua versione modificabile interna,_score
.
init {
...
_score.value = 0
...
}
...
fun onSkip() {
if (!wordList.isEmpty()) {
_score.value = (score.value)?.minus(1)
}
...
}
fun onCorrect() {
if (!wordList.isEmpty()) {
_score.value = (score.value)?.plus(1)
}
...
}
- Rinomina l'oggetto
word
in_word
e aggiungi una proprietà di supporto, come hai fatto per l'oggettoscore
.
// The current word
private val _word = MutableLiveData<String>()
val word: LiveData<String>
get() = _word
...
init {
_word.value = ""
...
}
...
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
_word.value = wordList.removeAt(0)
}
}
Ottimo lavoro, hai incapsulato gli oggetti LiveData
word
e score
.
L'app corrente passa alla schermata del punteggio quando l'utente tocca il pulsante Termina gioco. Vuoi anche che l'app acceda alla schermata del punteggio quando i giocatori passano da una parola all'altra. Dopo che i giocatori hanno finito con l'ultima parola, vuoi che il gioco termini automaticamente, in modo che l'utente non debba toccare il pulsante.
Per implementare questa funzionalità, devi attivare un evento e comunicarlo al frammento da ViewModel
quando tutte le parole sono state mostrate. Per farlo, utilizza il pattern osservatore LiveData
per modellare un evento completato nel gioco.
Il pattern dell'osservatore
Il pattern dell'osservatore è un pattern di progettazione del software. Specifica la comunicazione tra gli oggetti: un osservabile (l'oggetto "osservatorio" dell'osservazione) e osservatori. Un oggetto osservabile è un oggetto che notifica agli osservatori i cambiamenti nel proprio stato.
Nel caso di LiveData
in questa app, l'osservatore (oggetto) è l'oggetto LiveData
e gli osservatori sono i metodi nei controller dell'interfaccia utente, come i frammenti. Ogni volta che i dati inseriti nel codice LiveData
vengono modificati, viene applicata una modifica di stato. Le classi LiveData
sono fondamentali per comunicare da ViewModel
al frammento.
Passaggio 1: usa LiveData per rilevare un evento completato dal gioco
In questa attività, utilizzerai il pattern osservatore LiveData
per modellare un evento completato nel gioco.
- In
GameViewModel
, crea un oggettoBoolean
MutableLiveData
chiamato_eventGameFinish
. Questo oggetto conterrà l'evento completato nel gioco. - Dopo aver inizializzato l'oggetto
_eventGameFinish
, crea e inizializza una proprietà di supporto denominataeventGameFinish
.
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
get() = _eventGameFinish
- In
GameViewModel
, aggiungi un metodoonGameFinish()
. Nel metodo, imposta l'evento completato nel gioco,eventGameFinish
, sutrue
.
/** Method for the game completed event **/
fun onGameFinish() {
_eventGameFinish.value = true
}
- In
GameViewModel
, all'interno del metodonextWord()
, termina il gioco se l'elenco di parole è vuoto.
private fun nextWord() {
if (wordList.isEmpty()) {
onGameFinish()
} else {
//Select and remove a _word from the list
_word.value = wordList.removeAt(0)
}
}
- In
GameFragment
, all'interno dionCreateView()
, dopo aver inizializzatoviewModel
, allega un osservatore aeventGameFinish
. Utilizza il metodoobserve()
. All'interno della funzione lambda, chiama il metodogameFinished()
.
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
if (hasFinished) gameFinished()
})
- Esegui l'app, usa il gioco e rivedi tutte le parole. L'app passa automaticamente alla schermata del punteggio, anziché rimanere nel frammento del gioco finché non tocchi Termina gioco.
Dopo aver vuoto l'elenco di parole, viene impostatoeventGameFinish
, viene chiamato il metodo di osservazione associato nel frammento del gioco e l'app passa al frammento dello schermo. - Il codice aggiunto ha introdotto un problema del ciclo di vita. Per capire il problema, aggiungi un codice di navigazione nel metodo
gameFinished()
nella classeGameFragment
. Assicurati di conservare il messaggioToast
nel metodo.
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
// val action = GameFragmentDirections.actionGameToScore()
// action.score = viewModel.score.value?:0
// NavHostFragment.findNavController(this).navigate(action)
}
- Esegui l'app, usa il gioco e rivedi tutte le parole. Nella parte inferiore dello schermo viene visualizzato per poco tempo un messaggio toast che indica che il gioco è appena terminato.
Ora ruota il dispositivo o l'emulatore. Toast di nuovo visualizzato! Ruota il dispositivo un paio di volte e probabilmente vedrai il toast ogni volta. Questo è un bug, perché il toast dovrebbe essere visualizzato solo una volta, quando il gioco è terminato. Il toast non deve essere visualizzato ogni volta che un frammento viene ricreato. Risolvi il problema nella prossima attività.
Passaggio 2: reimposta l'evento completato
In genere, LiveData
offre aggiornamenti agli osservatori solo quando i dati cambiano. Un'eccezione a questo comportamento è che gli osservatori ricevono anche aggiornamenti quando lo spettatore passa da inattivo a attivo.
Questo è il motivo per cui il toast completato nel gioco viene attivato ripetutamente nell'app. Quando il frammento del gioco viene ricreato dopo una rotazione dello schermo, passa da uno stato inattivo a uno attivo. L'osservatore nel frammento viene ricollegato alla ViewModel
esistente e riceve i dati correnti. Il metodo gameFinished()
viene riattivato e viene visualizzato il toast.
In questa attività, risolvi il problema e visualizzi il toast una sola volta, reimpostando il flag eventGameFinish
in GameViewModel
.
- In
GameViewModel
, aggiungi un metodoonGameFinishComplete()
per reimpostare l'evento di fine del gioco,_eventGameFinish
.
/** Method for the game completed event **/
fun onGameFinishComplete() {
_eventGameFinish.value = false
}
- In
GameFragment
, alla fine digameFinished()
, chiamaonGameFinishComplete()
nell'oggettoviewModel
. (per ora lascia un commento nel codice di navigazione ingameFinished()
).
private fun gameFinished() {
...
viewModel.onGameFinishComplete()
}
- Esegui l'app e gioca. Rileggi tutte le parole, quindi modifica l'orientamento dello schermo del dispositivo. La notifica toast viene visualizzata una sola volta.
- In
GameFragment
, all'interno del metodogameFinished()
, rimuovi il commento dal codice di navigazione.
Per annullare il commento in Android Studio, seleziona le righe che sono state commentate e premiControl+/
(Command+/
su un Mac).
private fun gameFinished() {
Toast.makeText(activity, "Game has just finished", Toast.LENGTH_SHORT).show()
val action = GameFragmentDirections.actionGameToScore()
action.score = viewModel.score.value?:0
findNavController(this).navigate(action)
viewModel.onGameFinishComplete()
}
Se richiesto da Android Studio, importa androidx.navigation.fragment.NavHostFragment.findNavController
.
- Esegui l'app e gioca. Assicurati che l'app passi automaticamente alla schermata del punteggio finale dopo aver letto tutte le parole.
Ottimo. La tua app utilizza LiveData
per attivare un evento terminato dal gioco per comunicare da GameViewModel
al frammento del gioco che indica che l'elenco di parole è vuoto. Il frammento del gioco passa quindi al frammento del punteggio.
In questa attività, modifichi il punteggio in un oggetto LiveData
in ScoreViewModel
e colleghi un osservatore. L'attività è simile a quella che hai eseguito quando hai aggiunto LiveData
a GameViewModel
.
Tu apporti queste modifiche a ScoreViewModel
per completezza, in modo che tutti i dati della tua app utilizzino LiveData
.
- In
ScoreViewModel
, modifica il tipo di variabilescore
inMutableLiveData
. Rinominalo come convenzione per_score
e aggiungi una proprietà di supporto.
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
get() = _score
- In
ScoreViewModel
, all'interno del bloccoinit
, inizializza_score
. Puoi rimuovere o lasciare il log nel bloccoinit
come preferisci.
init {
_score.value = finalScore
}
- In
ScoreFragment
, all'interno dionCreateView()
, dopo aver inizializzatoviewModel
, allega un osservatore per l'oggetto punteggioLiveData
. All'interno dell'espressione lambda, imposta il valore del punteggio sulla visualizzazione del testo del punteggio. Rimuovi daViewModel
il codice che assegna direttamente la visualizzazione di testo con il valore del punteggio.
Codice da aggiungere:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
Codice da rimuovere:
binding.scoreText.text = viewModel.score.toString()
Quando richiesto da Android Studio, importa androidx.lifecycle.Observer
.
- Esegui l'app e gioca. L'app dovrebbe funzionare come prima, ma ora utilizza
LiveData
e un osservatore per aggiornare il punteggio.
In questa attività, aggiungi un pulsante Riproduci di nuovo nella schermata del punteggio e implementa il listener di clic utilizzando un evento LiveData
. Il pulsante attiva un evento per passare dalla schermata del punteggio alla schermata del gioco.
Il codice di avvio dell'app include il pulsante Riproduci di nuovo, ma è nascosto.
- In
res/layout/score_fragment.xml
, per il pulsanteplay_again_button
, cambia il valore dell'attributovisibility
invisible
.
<Button
android:id="@+id/play_again_button"
...
android:visibility="visible"
/>
- In
ScoreViewModel
, aggiungi un oggettoLiveData
per contenere unBoolean
chiamato_eventPlayAgain
. Questo oggetto viene utilizzato per salvare l'eventoLiveData
per passare dalla schermata del punteggio alla schermata del gioco.
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
get() = _eventPlayAgain
- In
ScoreViewModel
, definisci i metodi per impostare e reimpostare l'evento,_eventPlayAgain
.
fun onPlayAgain() {
_eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
_eventPlayAgain.value = false
}
- In
ScoreFragment
, aggiungi un osservatore pereventPlayAgain
. Inserisci il codice alla fine dionCreateView()
, prima dell'istruzionereturn
. All'interno dell'espressione lambda, torna alla schermata del gioco e reimpostaeventPlayAgain
.
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
if (playAgain) {
findNavController().navigate(ScoreFragmentDirections.actionRestart())
viewModel.onPlayAgainComplete()
}
})
Importa androidx.navigation.fragment.findNavController
, quando richiesto da Android Studio.
- In
ScoreFragment
, all'interno dionCreateView()
, aggiungi un listener di clic al pulsante PlayAgain e chiamaviewModel
.onPlayAgain()
.
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }
- Esegui l'app e gioca. Al termine della partita, nella schermata dei punteggi viene visualizzato il punteggio finale e il pulsante Gioca di nuovo. Tocca il pulsante PlayAgain e l'app va alla schermata del gioco per giocare di nuovo.
Ottimo! Hai modificato l'architettura della tua app in modo da utilizzare gli oggetti LiveData
in ViewModel
e hai associato gli osservatori agli oggetti LiveData
. LiveData
avvisa gli oggetti dell'osservatore quando cambia il valore detenuto da LiveData
.
Progetto Android Studio: GuessTheWord
Dati LiveLive
LiveData
è una classe di dati osservabili sensibile al ciclo di vita, uno dei componenti dell'architettura Android.- Puoi usare
LiveData
per attivare l'aggiornamento automatico dell'interfaccia utente quando i dati vengono aggiornati. LiveData
è osservabile, il che significa che un osservatore come un'attività o un frammento può essere avvisato quando i dati contenuti nell'oggettoLiveData
cambiano.LiveData
contiene dati; è un wrapper che può essere utilizzato con qualsiasi dato.LiveData
è sensibile al ciclo di vita, il che significa che aggiorna solo gli osservatori che si trovano in uno stato di ciclo di vita attivo, comeSTARTED
oRESUMED
.
Aggiungere LiveData
- Cambia il tipo di variabili dei dati in
ViewModel
inLiveData
oMutableLiveData
.
MutableLiveData
è un oggetto LiveData
il cui valore può essere modificato. MutableLiveData
è una classe generica, quindi devi specificare il tipo di dati che contiene.
- Per modificare il valore dei dati detenuti da
LiveData
, utilizza il metodosetValue()
sulla variabileLiveData
.
Per incapsulare i LiveData
LiveData
all'interno diViewModel
deve essere modificabile. Al di fuori diViewModel
, il campoLiveData
deve essere leggibile. Puoi implementarlo utilizzando una proprietà di supporto Kotlin.- Una proprietà di supporto Kotlin ti consente di restituire qualcosa da un getter diverso dall'oggetto esatto.
- Per incapsulare il
LiveData
, utilizzaprivate
MutableLiveData
all'interno diViewModel
e restituisci una proprietà di supportoLiveData
al di fuori diViewModel
.
LiveData osservabili
LiveData
segue uno schema di osservazione. L'oggetto"osservabile"è l'oggettoLiveData
e gli osservatori sono i metodi nei controller dell'interfaccia utente, come i frammenti. Ogni volta che i dati aggregati all'interno diLiveData
cambiano, i metodi di osservazione nei controller dell'interfaccia utente vengono informati.- Per rendere osservabile
LiveData
, collega un oggetto osservatore al riferimentoLiveData
in osservatori (come attività e frammenti) utilizzando il metodoobserve()
. - Questo pattern di osservazione
LiveData
può essere utilizzato per comunicare daViewModel
ai controller dell'interfaccia utente.
Corso Udacity:
Documentazione per gli sviluppatori Android:
Altro:
- Proprietà di supporto in Kotlin
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
Come incapsula il LiveData
archiviato in un ViewModel
in modo che gli oggetti esterni possano leggere i dati senza poterli aggiornare?
- Modifica il tipo di dati nell'oggetto
ViewModel
impostandolo suprivate
LiveData
. Utilizza una proprietà di supporto per esporre i dati di sola lettura del tipoMutableLiveData
. - Modifica il tipo di dati nell'oggetto
ViewModel
impostandolo suprivate
MutableLiveData
. Utilizza una proprietà di supporto per esporre i dati di sola lettura del tipoLiveData
. - All'interno del controller dell'interfaccia utente, modifica il tipo di dati in
private
MutableLiveData
. Utilizza una proprietà di supporto per esporre i dati di sola lettura del tipoLiveData
. - Modifica il tipo di dati nell'oggetto
ViewModel
impostandolo suLiveData
. Utilizza una proprietà di supporto per esporre i dati di sola lettura del tipoLiveData
.
Domanda 2
LiveData
aggiorna un controller dell'interfaccia utente (ad esempio un frammento) se si trova in quale dei seguenti stati?
- Hai ripreso
- In background
- In pausa
- Arrestata
Domanda 3
Nel modello dell'osservatore LiveData
, qual è l'elemento osservabile (cosa viene osservato)?
- Il metodo osservatore
- I dati in un oggetto
LiveData
- Il controller dell'interfaccia utente
- L'oggetto
ViewModel
Inizia la lezione successiva:
Per i link ad altri codelab in questo corso, consulta la pagina di destinazione di Android Kotlin Fundamentals.