Este codelab faz parte do curso Conceitos básicos do Kotlin para Android. Você vai aproveitar mais este curso se fizer os codelabs em sequência. Todos os codelabs do curso estão listados na página inicial dos codelabs de princípios básicos do Kotlin para Android.
Introdução
No codelab anterior, você usou um ViewModel
no app GuessTheWord para permitir que os dados do app sobrevivessem a mudanças na configuração do dispositivo. Neste codelab, você vai aprender a integrar o LiveData
com os dados nas classes ViewModel
. O LiveData
, um dos Componentes da arquitetura do Android, permite criar objetos de dados que notificam as visualizações quando o banco de dados muda.
Para usar a classe LiveData
, configure "observadores" (por exemplo, atividades ou fragmentos) que observam mudanças nos dados do app. O LiveData
é compatível com o ciclo de vida, então ele só atualiza os observadores de componentes do app que estão em um estado ativo do ciclo de vida.
O que você já precisa saber
- Como criar apps Android básicos em Kotlin.
- Como navegar entre os destinos do app.
- Ciclo de vida de atividades e fragmentos.
- Como usar objetos
ViewModel
no app. - Como criar objetos
ViewModel
usando a interfaceViewModelProvider.Factory
.
O que você vai aprender
- O que torna os objetos
LiveData
úteis. - Como adicionar
LiveData
aos dados armazenados em umViewModel
. - Quando e como usar o
MutableLiveData
. - Como adicionar métodos do observador para observar mudanças no
LiveData.
- Como encapsular
LiveData
usando uma propriedade de apoio. - Como se comunicar entre um controlador de UI e o
ViewModel
correspondente.
Atividades deste laboratório
- Use
LiveData
para a palavra e a pontuação no app GuessTheWord. - Adicione observadores que notam quando a palavra ou a pontuação muda.
- Atualize as visualizações de texto que mostram valores alterados.
- Use o padrão de observador
LiveData
para adicionar um evento de jogo concluído. - Implemente o botão Jogar novamente.
Nos codelabs da lição 5, você vai desenvolver o app GuessTheWord, começando com o código inicial. O GuessTheWord é um jogo de charadas para dois jogadores em que eles colaboram para conseguir a maior pontuação possível.
O primeiro jogador olha as palavras no app e representa cada uma delas, sem mostrar a palavra para o segundo jogador. O segundo jogador tenta adivinhar a palavra.
Para jogar, o primeiro jogador abre o app no dispositivo e vê uma palavra, por exemplo, "guitarra", como mostrado na captura de tela abaixo.
O primeiro jogador representa a palavra, tomando cuidado para não dizer a palavra em si.
- Quando o segundo jogador acerta a palavra, o primeiro pressiona o botão Entendi, que aumenta a contagem em um e mostra a próxima palavra.
- Se o segundo jogador não conseguir adivinhar a palavra, o primeiro jogador pressiona o botão Pular, que diminui a contagem em um e pula para a próxima palavra.
- Para encerrar o jogo, pressione o botão Encerrar jogo. Essa funcionalidade não está no código inicial do primeiro codelab da série.
Neste codelab, você vai melhorar o app GuessTheWord adicionando um evento para encerrar o jogo quando o usuário passar por todas as palavras no app. Você também vai adicionar um botão Jogar novamente no fragmento de pontuação para que o usuário possa jogar de novo.
Créditos | Tela do jogo | Tela de pontuação |
Nesta tarefa, você vai localizar e executar o código inicial deste codelab. Você pode usar o app GuessTheWord criado no codelab anterior como código inicial ou baixar um app inicial.
- (Opcional) Se você não estiver usando o código do codelab anterior, faça o download do código inicial para este codelab. Descompacte o código e abra o projeto no Android Studio.
- Execute o app e jogue.
- O botão Pular mostra a próxima palavra e diminui a pontuação em um, e o botão Entendi mostra a próxima palavra e aumenta a pontuação em um. O botão Encerrar jogo encerra a partida.
LiveData
é uma classe armazenadora de dados observáveis compatível com o ciclo de vida. Por exemplo, você pode incluir um LiveData
na pontuação atual do app GuessTheWord. Neste codelab, você vai aprender sobre várias características do LiveData
:
- O
LiveData
é observável, o que significa que um observador é notificado quando os dados contidos no objetoLiveData
mudam. - O
LiveData
armazena dados.LiveData
é um wrapper que pode ser usado com qualquer tipo de dados. - O
LiveData
é compatível com o ciclo de vida, o que significa que ele só atualiza os observadores que estão em um estado ativo do ciclo de vida, comoSTARTED
ouRESUMED
.
Nesta tarefa, você vai aprender a unir qualquer tipo de dados em objetos LiveData
convertendo a pontuação atual e os dados da palavra atual no GameViewModel
para LiveData
. Em uma tarefa posterior, você adicionará um observador a esses objetos LiveData
e aprenderá a observar o LiveData
.
Etapa 1: mudar a pontuação e a palavra para usar LiveData
- No pacote
screens/game
, abra o arquivoGameViewModel
. - Mude o tipo das variáveis
score
eword
paraMutableLiveData
.MutableLiveData
é umLiveData
cujo valor pode ser mudado.MutableLiveData
é uma classe genérica, então é necessário especificar o tipo de dados que ela contém.
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()
- Em
GameViewModel
, dentro do blocoinit
, inicializescore
eword
. Para mudar o valor de uma variávelLiveData
, use o métodosetValue()
na variável. Em Kotlin, você pode chamarsetValue()
usando a propriedadevalue
.
init {
word.value = ""
score.value = 0
...
}
Etapa 2: atualizar a referência do objeto LiveData
As variáveis score
e word
agora são do tipo LiveData
. Nesta etapa, você muda as referências a essas variáveis usando a propriedade value
.
- Em
GameViewModel
, no métodoonSkip()
, mudescore
parascore.value
. Observe o erro sobrescore
possivelmente sernull
. Você vai corrigir esse erro em seguida. - Para resolver o erro, adicione uma verificação de
null
ascore.value
emonSkip()
. Em seguida, chame a funçãominus()
emscore
, que realiza a subtração com segurança denull
.
fun onSkip() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.minus(1)
}
nextWord()
}
- Atualize o método
onCorrect()
da mesma forma: adicione uma verificaçãonull
à variávelscore
e use a funçãoplus()
.
fun onCorrect() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.plus(1)
}
nextWord()
}
- No
GameViewModel
, no métodonextWord()
, mude a referênciaword
paraword
.
value
.
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
word.value = wordList.removeAt(0)
}
}
- No
GameFragment
, no métodoupdateWordText()
, mude a referência deviewModel
.word
paraviewModel
.
word
.
value.
/** Methods for updating the UI **/
private fun updateWordText() {
binding.wordText.text = viewModel.word.value
}
- No método
updateScoreText()
doGameFragment
, mude a referência deviewModel
.score
paraviewModel
.
score
.
value.
private fun updateScoreText() {
binding.scoreText.text = viewModel.score.value.toString()
}
- No
GameFragment
, no métodogameFinished()
, mude a referência deviewModel
.score
paraviewModel
.
score
.
value
. Adicione a verificação de segurançanull
necessária.
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)
}
- Verifique se não há erros no código. Compile e execute o app. A funcionalidade dele deve ser a mesma de antes.
Essa tarefa está intimamente relacionada à anterior, em que você converteu os dados de pontuação e palavras em objetos LiveData
. Nesta tarefa, você vai anexar objetos Observer
aos objetos LiveData
.
- Em
GameFragment,
, dentro do métodoonCreateView()
, anexe um objetoObserver
ao objetoLiveData
da pontuação atual,viewModel.score
. Use o métodoobserve()
e coloque o código após a inicialização doviewModel
. Use uma expressão lambda para simplificar o código. Uma expressão lambda é uma função anônima que não é declarada, mas é transmitida imediatamente como uma expressão.
viewModel.score.observe(this, Observer { newScore ->
})
Resolva a referência a Observer
. Para fazer isso, clique em Observer
, pressione Alt+Enter
(Option+Enter
em um Mac) e importe androidx.lifecycle.Observer
.
- O observador que você acabou de criar recebe um evento quando os dados contidos no objeto
LiveData
observado mudam. Dentro do observador, atualize a pontuaçãoTextView
com a nova pontuação.
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- Anexe um objeto
Observer
ao objetoLiveData
da palavra atual. Faça isso da mesma forma que anexou um objetoObserver
à pontuação atual.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
Quando o valor de score
ou word
muda, o score
ou word
exibido na tela é atualizado automaticamente.
- Em
GameFragment
, exclua os métodosupdateWordText()
eupdateScoreText()
e todas as referências a eles. Eles não são mais necessários porque as visualizações de texto são atualizadas pelos métodos de observadorLiveData
. - Execute o app. Ele vai funcionar exatamente como antes, mas agora usa observadores
LiveData
eLiveData
.
O encapsulamento é uma maneira de restringir o acesso direto a alguns dos campos de um objeto. Ao encapsular um objeto, você expõe um conjunto de métodos públicos que modificam os campos internos particulares. Usando o encapsulamento, você controla como outras classes manipulam os campos internos.
No seu código atual, qualquer classe externa pode modificar as variáveis score
e word
usando a propriedade value
, por exemplo, usando viewModel.score.value
. Isso pode não importar no app que você está desenvolvendo neste codelab, mas, em um app de produção, é importante ter controle sobre os dados nos objetos ViewModel
.
Somente o ViewModel
pode editar os dados no app. No entanto, os controladores de interface precisam ler os dados, então os campos de dados não podem ser completamente particulares. Para encapsular os dados do app, use objetos MutableLiveData
e LiveData
.
MutableLiveData
x LiveData
:
- Os dados em um objeto
MutableLiveData
podem ser alterados, como o nome sugere. NoViewModel
, os dados precisam ser editáveis. Portanto, eles usamMutableLiveData
. - Os dados em um objeto
LiveData
podem ser lidos, mas não alterados. Fora doViewModel
, os dados precisam ser legíveis, mas não editáveis, portanto, os dados precisam ser expostos comoLiveData
.
Para realizar essa estratégia, use uma propriedade de apoio do Kotlin. Uma propriedade de apoio permite que você retorne algo de um getter diferente do objeto exato. Nesta tarefa, você vai implementar uma propriedade de suporte para os objetos score
e word
no app GuessTheWord.
Adicionar uma propriedade de apoio à pontuação e à palavra
- Em
GameViewModel
, faça com que o objetoscore
atual sejaprivate
. - Para seguir a convenção de nomenclatura usada em propriedades de apoio, mude
score
para_score
. A propriedade_score
agora é a versão mutável da pontuação do jogo, para ser usada internamente. - Crie uma versão pública do tipo
LiveData
, chamadascore
.
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
- Você vai encontrar um erro de inicialização. Esse erro ocorre porque, dentro do
GameFragment
, oscore
é uma referênciaLiveData
, e oscore
não pode mais acessar o setter. Para saber mais sobre getters e setters em Kotlin, consulte Getters e setters.
Para resolver o erro, substitua o métodoget()
do objetoscore
emGameViewModel
e retorne a propriedade de suporte,_score
.
val score: LiveData<Int>
get() = _score
- No
GameViewModel
, mude as referências descore
para a versão mutável 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)
}
...
}
- Renomeie o objeto
word
para_word
e adicione uma propriedade de apoio a ele, como fez com o objetoscore
.
// 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)
}
}
Muito bem! Você encapsulou os objetos LiveData
word
e score
.
O app atual navega até a tela de pontuação quando o usuário toca no botão Encerrar jogo. Você também quer que o app navegue até a tela de pontuação quando os jogadores tiverem passado por todas as palavras. Depois que os jogadores terminarem a última palavra, você vai querer que o jogo termine automaticamente para que o usuário não precise tocar no botão.
Para implementar essa funcionalidade, você precisa de um evento que seja acionado e comunicado ao fragmento do ViewModel
quando todas as palavras forem mostradas. Para isso, use o padrão de observador LiveData
para modelar um evento de jogo concluído.
O padrão de observador
O padrão de observador é um padrão de design de software. Ele especifica a comunicação entre objetos: um observável (o "assunto" da observação) e observadores. Um observável é um objeto que notifica os observadores sobre as mudanças no estado dele.
No caso do LiveData
neste app, o observável (assunto) é o objeto LiveData
, e os observadores são os métodos nos controladores de UI, como fragmentos. Uma mudança de estado acontece sempre que os dados envolvidos em LiveData
mudam. As classes LiveData
são cruciais para a comunicação da ViewModel
com o fragmento.
Etapa 1: usar LiveData para detectar um evento de fim de jogo
Nesta tarefa, você vai usar o padrão de observador LiveData
para modelar um evento de jogo concluído.
- Em
GameViewModel
, crie um objetoBoolean
MutableLiveData
chamado_eventGameFinish
. Esse objeto vai conter o evento de término do jogo. - Depois de inicializar o objeto
_eventGameFinish
, crie e inicialize uma propriedade de suporte chamadaeventGameFinish
.
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
get() = _eventGameFinish
- Em
GameViewModel
, adicione um métodoonGameFinish()
. No método, defina o evento de jogo concluído,eventGameFinish
, comotrue
.
/** Method for the game completed event **/
fun onGameFinish() {
_eventGameFinish.value = true
}
- Em
GameViewModel
, dentro do métodonextWord()
, encerre o jogo se a lista de palavras estiver vazia.
private fun nextWord() {
if (wordList.isEmpty()) {
onGameFinish()
} else {
//Select and remove a _word from the list
_word.value = wordList.removeAt(0)
}
}
- Em
GameFragment
, dentro deonCreateView()
, depois de inicializar oviewModel
, anexe um observador aeventGameFinish
. Use o métodoobserve()
. Na função lambda, chame o métodogameFinished()
.
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
if (hasFinished) gameFinished()
})
- Execute o app, jogue e passe por todas as palavras. O app navega automaticamente para a tela de pontuação, em vez de ficar no fragmento do jogo até que você toque em Encerrar jogo.
Depois que a lista de palavras estiver vazia,eventGameFinish
será definido, o método observador associado no fragmento do jogo será chamado, e o app vai navegar até o fragmento da tela. - O código adicionado introduziu um problema de ciclo de vida. Para entender o problema, na classe
GameFragment
, use um comentário para excluir o código de navegação no métodogameFinished()
. Não se esqueça de manter a mensagemToast
no método.
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)
}
- Execute o app, jogue e passe por todas as palavras. Uma mensagem de aviso "O jogo acabou de terminar" aparece brevemente na parte de baixo da tela do jogo, que é o comportamento esperado.
Agora, gire o dispositivo ou emulador. O aviso aparece de novo. Gire o dispositivo mais algumas vezes. É provável que o aviso apareça todas as vezes. Isso é um bug, porque o toast só deve aparecer uma vez, quando o jogo termina. O toast não deve aparecer toda vez que o fragmento for recriado. Você vai resolver esse problema na próxima tarefa.
Etapa 2: redefinir o evento de término do jogo
Normalmente, o LiveData
envia atualizações aos observadores apenas quando os dados mudam. Uma exceção desse comportamento é que os observadores também recebem atualizações quando passam de um estado inativo para um ativo.
É por isso que o toast de jogo concluído é acionado repetidamente no app. Quando o fragmento do jogo é recriado após uma rotação de tela, ele passa de um estado inativo para um estado ativo. O observador no fragmento é reconectado ao ViewModel
atual e recebe os dados atuais. O método gameFinished()
é acionado novamente, e o toast é exibido.
Nesta tarefa, você vai corrigir esse problema e mostrar o toast apenas uma vez, redefinindo a flag eventGameFinish
no GameViewModel
.
- Em
GameViewModel
, adicione um métodoonGameFinishComplete()
para redefinir o evento de término do jogo,_eventGameFinish
.
/** Method for the game completed event **/
fun onGameFinishComplete() {
_eventGameFinish.value = false
}
- Em
GameFragment
, ao final degameFinished()
, chameonGameFinishComplete()
no objetoviewModel
. Por enquanto, deixe o código de navegação emgameFinished()
comentado.
private fun gameFinished() {
...
viewModel.onGameFinishComplete()
}
- Execute o app e jogue. Leia todas as palavras e mude a orientação da tela do dispositivo. O toast é mostrado apenas uma vez.
- Em
GameFragment
, dentro do métodogameFinished()
, remova o comentário do código de navegação.
Para remover o comentário no Android Studio, selecione as linhas comentadas e pressioneControl+/
(Command+/
em um 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 solicitado pelo Android Studio, importe androidx.navigation.fragment.NavHostFragment.findNavController
.
- Execute o app e jogue. Verifique se o app navega automaticamente para a tela de pontuação final depois que você passa por todas as palavras.
Muito bem! Seu app usa LiveData
para acionar um evento de jogo concluído e comunicar do GameViewModel
ao fragmento do jogo que a lista de palavras está vazia. Em seguida, o fragmento do jogo navega até o fragmento de pontuação.
Nesta tarefa, você vai mudar a pontuação para um objeto LiveData
no ScoreViewModel
e anexar um observador a ele. Essa tarefa é semelhante ao que você fez ao adicionar LiveData
ao GameViewModel
.
Você faz essas mudanças em ScoreViewModel
para garantir que todos os dados no app usem LiveData
.
- Em
ScoreViewModel
, mude o tipo da variávelscore
paraMutableLiveData
. Renomeie por convenção para_score
e adicione uma propriedade de apoio.
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
get() = _score
- Em
ScoreViewModel
, dentro do blocoinit
, inicialize_score
. Você pode remover ou deixar o registro no blocoinit
como quiser.
init {
_score.value = finalScore
}
- No
ScoreFragment
, dentro deonCreateView()
, depois de inicializar oviewModel
, anexe um observador ao objetoLiveData
de pontuação. Na expressão lambda, defina o valor da pontuação na visualização de texto da pontuação. Remova o código que atribui diretamente a visualização de texto com o valor da pontuação doViewModel
.
Código para adicionar:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
Código a ser removido:
binding.scoreText.text = viewModel.score.toString()
Quando solicitado pelo Android Studio, importe androidx.lifecycle.Observer
.
- Execute o app e jogue uma partida. O app vai funcionar como antes, mas agora ele usa
LiveData
e um observador para atualizar a pontuação.
Nesta tarefa, você vai adicionar um botão Jogar de novo à tela de pontuação e implementar o listener de clique dele usando um evento LiveData
. O botão aciona um evento para navegar da tela de pontuação para a tela do jogo.
O código inicial do app inclui o botão Jogar de novo, mas ele está oculto.
- Em
res/layout/score_fragment.xml
, para o botãoplay_again_button
, mude o valor do atributovisibility
paravisible
.
<Button
android:id="@+id/play_again_button"
...
android:visibility="visible"
/>
- Em
ScoreViewModel
, adicione um objetoLiveData
para armazenar umBoolean
chamado_eventPlayAgain
. Esse objeto é usado para salvar o eventoLiveData
e navegar da tela de pontuação para a tela do jogo.
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
get() = _eventPlayAgain
- Em
ScoreViewModel
, defina métodos para definir e redefinir o evento,_eventPlayAgain
.
fun onPlayAgain() {
_eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
_eventPlayAgain.value = false
}
- Em
ScoreFragment
, adicione um observador paraeventPlayAgain
. Coloque o código no fim deonCreateView()
, antes da instruçãoreturn
. Dentro da expressão lambda, volte para a tela do jogo e redefinaeventPlayAgain
.
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
if (playAgain) {
findNavController().navigate(ScoreFragmentDirections.actionRestart())
viewModel.onPlayAgainComplete()
}
})
Importe androidx.navigation.fragment.findNavController
quando solicitado pelo Android Studio.
- Em
ScoreFragment
, dentro deonCreateView()
, adicione um listener de clique ao botão PlayAgain e chameviewModel
.onPlayAgain()
.
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }
- Execute o app e jogue uma partida. Quando o jogo termina, a tela de pontuação mostra a pontuação final e o botão Jogar de novo. Toque no botão PlayAgain. O app vai navegar até a tela do jogo para que você possa jogar de novo.
Bom trabalho! Você mudou a arquitetura do app para usar objetos LiveData
no ViewModel
e anexou observadores aos objetos LiveData
. O LiveData
notifica objetos observadores quando o valor mantido pelo LiveData
muda.
Projeto do Android Studio: GuessTheWord (link em inglês)
LiveData
- O
LiveData
é uma classe armazenadora de dados observáveis compatível com o ciclo de vida, um dos Componentes da arquitetura do Android. - Você pode usar
LiveData
para permitir que a interface seja atualizada automaticamente quando os dados forem atualizados. - O
LiveData
é observável, o que significa que um observador, como uma atividade ou um fragmento, pode ser notificado quando os dados contidos no objetoLiveData
mudam. - O
LiveData
armazena dados. Ele é um wrapper que pode ser usado com qualquer tipo de dado. - O
LiveData
é compatível com o ciclo de vida, o que significa que ele só atualiza os observadores que estão em um estado ativo do ciclo de vida, comoSTARTED
ouRESUMED
.
Para adicionar o LiveData
- Mude o tipo das variáveis de dados em
ViewModel
paraLiveData
ouMutableLiveData
.
MutableLiveData
é um objeto LiveData
cujo valor pode ser mudado. MutableLiveData
é uma classe genérica, então é necessário especificar o tipo de dados que ela contém.
- Para mudar o valor dos dados mantidos pelo
LiveData
, use o métodosetValue()
na variávelLiveData
.
Para encapsular LiveData
- O
LiveData
dentro doViewModel
precisa ser editável. Fora doViewModel
, oLiveData
precisa estar legível. Isso pode ser implementado usando uma propriedade de apoio do Kotlin. - Uma propriedade de apoio do Kotlin permite que você retorne algo de um getter diferente do objeto exato.
- Para encapsular o
LiveData
, useprivate
MutableLiveData
dentro doViewModel
e retorne uma propriedade de suporteLiveData
fora doViewModel
.
LiveData observável
LiveData
segue um padrão de observador. O "observável" é o objetoLiveData
, e os observadores são os métodos nos controladores de UI, como fragmentos. Sempre que os dados envolvidos emLiveData
mudam, os métodos de observador nos controladores de UI são notificados.- Para tornar o
LiveData
observável, anexe um objeto observador à referênciaLiveData
nos observadores (como atividades e fragmentos) usando o métodoobserve()
. - Esse padrão de observador
LiveData
pode ser usado para se comunicar doViewModel
com os controladores da interface.
Curso da Udacity:
Documentação do desenvolvedor Android:
Outro:
- Propriedade de apoio em Kotlin
Esta seção lista as possíveis atividades de dever de casa para os alunos que estão fazendo este codelab como parte de um curso ministrado por um professor. Cabe ao professor fazer o seguinte:
- Atribuir o dever de casa, se necessário.
- Informar aos alunos como enviar deveres de casa.
- Atribuir nota aos deveres de casa.
Os professores podem usar essas sugestões o quanto quiserem, podendo passar os exercícios que acharem mais apropriados como dever de casa.
Se você estiver seguindo este codelab por conta própria, sinta-se à vontade para usar esses deveres de casa para testar seu conhecimento.
Responda estas perguntas
Pergunta 1
Como encapsular o LiveData
armazenado em um ViewModel
para que objetos externos possam ler dados sem atualizá-los?
- Dentro do objeto
ViewModel
, mude o tipo de dados paraprivate
LiveData
. Use uma propriedade de backup para expor dados somente leitura do tipoMutableLiveData
. - Dentro do objeto
ViewModel
, mude o tipo de dados paraprivate
MutableLiveData
. Use uma propriedade de backup para expor dados somente leitura do tipoLiveData
. - Dentro do controlador de interface, mude o tipo de dados para
private
MutableLiveData
. Use uma propriedade de backup para expor dados somente leitura do tipoLiveData
. - Dentro do objeto
ViewModel
, mude o tipo de dados paraLiveData
. Use uma propriedade de backup para expor dados somente leitura do tipoLiveData
.
Pergunta 2
O LiveData
vai atualizar um controlador de UI (por exemplo, um fragmento) se esse controlador estiver em qual dos seguintes estados?
- Retomado
- Em segundo plano
- Pausado
- Interrompida
Pergunta 3
No padrão do observador LiveData
, qual é o item observável (o que é observado)?
- O método do observador
- Os dados em um objeto
LiveData
- O controlador de IU
- O objeto
ViewModel
Comece a próxima lição:
Para acessar links de outros codelabs neste curso, consulte a página inicial dos codelabs de conceitos básicos do Kotlin para Android.