Cet atelier de programmation fait partie du cours Android Kotlin Fundamentals. Vous tirerez le meilleur parti de ce cours si vous suivez les ateliers de programmation dans l'ordre. Tous les ateliers de programmation du cours sont répertoriés sur la page de destination des ateliers de programmation Android Kotlin Fundamentals.
Présentation
Dans l'atelier de programmation précédent, vous avez utilisé un ViewModel
dans l'application GuessTheWord pour permettre aux données de l'application de survivre aux modifications de configuration de l'appareil. Dans cet atelier de programmation, vous allez apprendre à intégrer LiveData
aux données des classes ViewModel
. LiveData
, l'un des composants d'architecture Android, vous permet de créer des objets de données qui avertissent les vues lorsque la base de données sous-jacente est modifiée.
Pour utiliser la classe LiveData
, vous devez configurer des"observateurs" (par exemple, des activités ou des fragments) qui observent des changements dans les données de l'application. LiveData
tient compte du cycle de vie, il ne met donc à jour que les observateurs de composants d'application qui sont actifs.
Ce que vous devez déjà savoir
- Créer des applications Android de base en Kotlin
- Comment parcourir les destinations de votre application
- Cycle de vie des activités et des fragments.
- Utiliser les objets
ViewModel
dans votre application - Créer des objets
ViewModel
à l'aide de l'interfaceViewModelProvider.Factory
Points abordés
- Objets
LiveData
utiles. - Comment ajouter
LiveData
aux données stockées dans unViewModel
. - Quand et comment utiliser
MutableLiveData
- Ajouter des méthodes d'observation afin d'observer les changements dans la
LiveData.
- Comment encapsuler
LiveData
à l'aide d'une propriété de support. - Communication entre un contrôleur d'interface utilisateur et le
ViewModel
correspondant
Objectifs de l'atelier
- Utilisez
LiveData
pour le mot et le score dans l'application GuessTheWord. - Ajoutez des observateurs qui remarqueront la modification du mot ou du score.
- Mettez à jour les vues de texte qui affichent les valeurs modifiées.
- Utilisez le schéma d'observateur
LiveData
pour ajouter un événement terminé. - Intégrez le bouton Play Again (Rejouer).
Dans les ateliers de programmation de la leçon 5, vous allez développer l'application GuessTheWord en commençant par le code de démarrage. GuessTheWord est un jeu de charades à deux joueurs, où les joueurs collaborent pour obtenir le meilleur score possible.
Le premier joueur analyse les mots dans l'application et les joue tous à tour de rôle. Veillez donc à ne pas afficher le mot au deuxième joueur. Le deuxième joueur essaie de deviner le mot.
Pour lancer ce jeu, le premier joueur ouvre l'application sur l'appareil et voit un mot, par exemple "guitare", comme illustré dans la capture d'écran ci-dessous.
Le premier joueur joue le mot, en prenant soin de ne pas le prononcer.
- Lorsque le deuxième joueur essaie de deviner le mot, le premier appuie sur le bouton OK, ce qui augmente le nombre de points et affiche le mot suivant.
- S'il ne parvient pas à deviner le mot, le premier joueur appuie sur le bouton Ignorer, ce qui diminue le nombre de fois jusqu'à l'affichage du mot suivant.
- Pour terminer la partie, appuyez sur le bouton Terminer le jeu. (Cette fonctionnalité n'est pas disponible dans le code de démarrage du premier atelier de programmation de cette série.)
Dans cet atelier de programmation, vous allez améliorer l'application GuessTheWord en ajoutant un événement pour terminer le jeu lorsque l'utilisateur fait défiler les mots dans l'application. Vous ajoutez également un bouton Play Again (Rejouer) dans le fragment de score, pour que l'utilisateur puisse rejouer.
Écran titre | Écran de jeu | Écran de score |
Dans cette tâche, vous allez localiser et exécuter le code de démarrage de cet atelier de programmation. Vous pouvez utiliser l'application GuessTheWord que vous avez créée dans l'atelier de programmation précédent comme code de démarrage. Vous pouvez également en télécharger une.
- (Facultatif) Si vous n'utilisez pas le code de l'atelier de programmation précédent, téléchargez-le. Décompressez le code, puis ouvrez le projet dans Android Studio.
- Exécutez l'application et jouez au jeu.
- Notez que le bouton Ignorer affiche le mot suivant et diminue le score de 1. Le bouton OK permet d'afficher le mot suivant et d'augmenter le score de 1. Le bouton Terminer le jeu met fin au jeu.
LiveData
est une classe de conteneur de données observable qui tient compte du cycle de vie. Par exemple, vous pouvez encapsuler un LiveData
autour du score actuel dans l'application GuessTheWord : dans cet atelier de programmation, vous allez découvrir plusieurs caractéristiques de LiveData
:
LiveData
est observable, ce qui signifie qu'un observateur est averti lorsque les données conservées par l'objetLiveData
sont modifiées.LiveData
contient des données ;LiveData
est un wrapper qui peut être utilisé avec toutes les donnéesLiveData
tient compte du cycle de vie, c'est-à-dire qu'il ne met à jour que les observateurs qui sont actifs dans leur cycle de vie (STARTED
ouRESUMED
, par exemple).
Dans cette tâche, vous allez apprendre à encapsuler un type de données dans des objets LiveData
en convertissant le score et les données de mots actuels dans GameViewModel
dans LiveData
. Plus tard, vous ajouterez un observateur à ces objets LiveData
et apprendrez à observer LiveData
.
Étape 1: Modifiez le score et le mot pour utiliser LiveData
- Sous le package
screens/game
, ouvrez le fichierGameViewModel
. - Remplacez le type des variables
score
etword
parMutableLiveData
.MutableLiveData
est unLiveData
dont la valeur peut être modifiée.MutableLiveData
est une classe générique. Vous devez donc spécifier le type de données qu'elle contient.
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()
- Dans
GameViewModel
, dans le blocinit
, initialisezscore
etword
. Pour modifier la valeur d'une variableLiveData
, utilisez la méthodesetValue()
sur cette variable. En langage Kotlin, vous pouvez appelersetValue()
à l'aide de la propriétévalue
.
init {
word.value = ""
score.value = 0
...
}
Étape 2: Mettez à jour la référence de l'objet LiveData
Les variables score
et word
sont désormais de type LiveData
. Au cours de cette étape, vous allez modifier les références à ces variables à l'aide de la propriété value
.
- Dans
GameViewModel
, dans la méthodeonSkip()
, remplacezscore
parscore.value
. Vous remarquerez qu'il s'agit probablement d'une erreurnull
pourscore
. Vous allez corriger cette erreur ensuite. - Pour résoudre l'erreur, ajoutez une vérification
null
àscore.value
dansonSkip()
. Appelez ensuite la fonctionminus()
surscore
, qui effectue la soustraction avecnull
-safety.
fun onSkip() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.minus(1)
}
nextWord()
}
- Mettez à jour la méthode
onCorrect()
de la même manière: ajoutez une vérificationnull
à la variablescore
et utilisez la fonctionplus()
.
fun onCorrect() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.plus(1)
}
nextWord()
}
- Dans
GameViewModel
, dans la méthodenextWord()
, remplacez la référenceword
parword
.
value
.
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
word.value = wordList.removeAt(0)
}
}
- Dans
GameFragment
, dans la méthodeupdateWordText()
, remplacez la référence parviewModel
.word
parviewModel
.
word
.
value.
/** Methods for updating the UI **/
private fun updateWordText() {
binding.wordText.text = viewModel.word.value
}
- Dans
GameFragment
, dans la méthodeupdateScoreText()
, remplacez la référence parviewModel
.score
parviewModel
.
score
.
value.
private fun updateScoreText() {
binding.scoreText.text = viewModel.score.value.toString()
}
- Dans
GameFragment
, dans la méthodegameFinished()
, remplacez la référence parviewModel
.score
parviewModel
.
score
.
value
. Ajoutez le contrôle de sécuriténull
requis.
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)
}
- Vérifiez que votre code ne contient pas d'erreurs. Compilez et exécutez votre application. La fonctionnalité de l'application doit être identique à celle utilisée précédemment.
Cette tâche est étroitement liée à la tâche précédente, qui consiste à convertir les données de score et de mots en objets LiveData
. Dans cette tâche, vous allez associer des objets Observer
à ces objets LiveData
.
- Dans la
GameFragment,
de la méthodeonCreateView()
, associez un objetObserver
à l'objetLiveData
pour obtenir le score actuel,viewModel.score
. Utilisez la méthodeobserve()
et insérez le code après l'initialisation deviewModel
. Utilisez une expression lambda pour simplifier le code. (Une expression lambda est une fonction anonyme qui n'est pas déclarée, mais qui est transmise immédiatement en tant qu'expression.
viewModel.score.observe(this, Observer { newScore ->
})
Résolvez la référence à Observer
. Pour ce faire, cliquez sur Observer
, appuyez sur Alt+Enter
(Option+Enter
sur un Mac), puis importez androidx.lifecycle.Observer
.
- L'observateur que vous venez de créer reçoit un événement lorsque les données conservées par l'objet
LiveData
observé sont modifiées. Dans l'observateur, mettez à jour le scoreTextView
avec le nouveau score.
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
- Associez un objet
Observer
à l'objet de motLiveData
actuel. Procédez de la même manière que vous associez un objetObserver
au score actuel.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})
Lorsque la valeur de score
ou de word
change, l'élément score
ou word
affiché à l'écran est désormais mis à jour automatiquement.
- Dans
GameFragment
, supprimez les méthodesupdateWordText()
etupdateScoreText()
, ainsi que toutes les références à celles-ci. Vous n'en avez plus besoin, car les vues de texte sont mises à jour par les méthodes d'observationLiveData
. - Exécutez votre application. Votre application de jeu devrait fonctionner exactement comme auparavant, mais elle utilise désormais
LiveData
et des observateursLiveData
.
L'encapsulation permet de restreindre l'accès direct à certains champs des objets. Lorsque vous encapsulez un objet, vous exposez un ensemble de méthodes publiques qui modifient les champs internes privés. L'encapsulation vous permet de contrôler la façon dont les autres classes manipulent ces champs internes.
Dans votre code actuel, toute classe externe peut modifier les variables score
et word
à l'aide de la propriété value
, par exemple en utilisant viewModel.score.value
. Peu importe l'application que vous développez dans cet atelier de programmation, mais dans une application en production, vous voulez contrôler les données des objets ViewModel
.
Seul le ViewModel
doit modifier les données de votre appli. Toutefois, les contrôleurs de l'interface utilisateur doivent lire les données, et les champs de données ne peuvent donc pas être totalement privés. Pour encapsuler les données de votre application, vous devez utiliser les objets MutableLiveData
et LiveData
.
MutableLiveData
et LiveData
:
- Les données d'un objet
MutableLiveData
peuvent être modifiées, comme son nom l'indique. DansViewModel
, les données doivent être modifiables. Elles utilisent doncMutableLiveData
. - Les données d'un objet
LiveData
peuvent être lues, mais pas modifiées. En dehors deViewModel
, les données doivent être lisibles, mais pas modifiables. Elles doivent donc être exposées en tant queLiveData
.
Pour mettre en œuvre cette stratégie, vous utilisez une propriété de support Kotlin. Une propriété de support vous permet de renvoyer un élément à partir d'un getter autre que l'objet exact. Dans cette tâche, vous allez implémenter une propriété de support pour les objets score
et word
dans l'application GuessTheWord.
Ajouter une propriété de support pour le score et le mot
- Dans
GameViewModel
, définissez l'objetscore
actuelprivate
. - Pour respecter la convention d'attribution de noms utilisée dans les propriétés de support, remplacez
score
par_score
. La propriété_score
est désormais la version modifiable du score de jeu, qui doit être utilisée en interne. - Créez une version publique du type
LiveData
, appeléescore
.
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
- Une erreur d'initialisation s'affiche. Cette erreur se produit, car au sein de
GameFragment
,score
est une référenceLiveData
, etscore
ne peut plus accéder à son setter. Pour en savoir plus sur les getters et les setters en langage Kotlin, consultez la section Getters et setters.
Pour résoudre l'erreur, ignorez la méthodeget()
pour l'objetscore
dansGameViewModel
, puis renvoyez la propriété de support_score
.
val score: LiveData<Int>
get() = _score
- Dans
GameViewModel
, remplacez les références descore
par sa version modifiable interne,_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)
}
...
}
- Renommez l'objet
word
en_word
et ajoutez une propriété de support, comme vous l'avez fait pour l'objetscore
.
// 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)
}
}
Bien joué, vous avez encapsulé les objets LiveData
word
et score
.
Votre application actuelle accède à l'écran de score lorsque l'utilisateur appuie sur le bouton End Game (Terminer le jeu). Vous voulez également que l'application accède à l'écran de score lorsque les joueurs ont parcouru tous les mots en même temps. Une fois que le joueur a terminé avec le dernier mot, le jeu doit se terminer automatiquement. L'utilisateur n'a donc pas besoin d'appuyer sur le bouton.
Pour implémenter cette fonctionnalité, vous devez déclencher un événement et communiquer au fragment à partir du ViewModel
lorsque tous les mots ont été affichés. Pour ce faire, vous utilisez le modèle d'observateur LiveData
pour modéliser un événement terminé.
Schéma d'observateur
Le modèle d'observateur est un modèle de conception logicielle. Il spécifie la communication entre les objets, un observable (l'objet d'observation) et des observateurs. Un observable est un objet qui informe les observateurs des modifications de son état.
Dans le cas de LiveData
dans cette application, l'observable (l'objet) est l'objet LiveData
, et les observateurs sont les méthodes des contrôleurs de l'interface utilisateur, comme les fragments. Un état est modifié chaque fois que les données encapsulées dans LiveData
changent. Les classes LiveData
sont essentielles pour communiquer entre le ViewModel
et le fragment.
Étape 1: Utilisez LiveData pour détecter un événement terminé dans le jeu
Dans cette tâche, vous allez utiliser le modèle d'observateur LiveData
pour modéliser un événement terminé.
- Dans
GameViewModel
, créez un objetBoolean
MutableLiveData
appelé_eventGameFinish
. Cet objet contient l'événement de jeu terminé. - Après avoir initialisé l'objet
_eventGameFinish
, créez et initialisez une propriété de support appeléeeventGameFinish
.
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
get() = _eventGameFinish
- Dans
GameViewModel
, ajoutez une méthodeonGameFinish()
. Dans la méthode, définissez l'événement terminé dans le jeueventGameFinish
surtrue
.
/** Method for the game completed event **/
fun onGameFinish() {
_eventGameFinish.value = true
}
- Dans
GameViewModel
, dans la méthodenextWord()
, mettez fin au jeu si la liste de mots est vide.
private fun nextWord() {
if (wordList.isEmpty()) {
onGameFinish()
} else {
//Select and remove a _word from the list
_word.value = wordList.removeAt(0)
}
}
- Dans
GameFragment
, dansonCreateView()
, après avoir initialiséviewModel
, ajoutez un observateur àeventGameFinish
. Utilisez la méthodeobserve()
. Dans le lambda, appelez la méthodegameFinished()
.
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
if (hasFinished) gameFinished()
})
- Exécutez votre application, jouez au jeu et parcourez tous les mots. L'application affiche l'écran de score automatiquement au lieu de rester dans le fragment du jeu jusqu'à ce que vous appuyiez sur Arrêter le jeu.
Une fois la liste de mots vide,eventGameFinish
est défini. La méthode d'observation associée dans le fragment de jeu est appelée, et l'application accède au fragment d'écran. - Le code que vous avez ajouté a introduit un problème de cycle de vie. Pour comprendre le problème, commentez le code de navigation dans la méthode
gameFinished()
dans la classeGameFragment
. Veillez à conserver le messageToast
dans la méthode.
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)
}
- Exécutez votre application, jouez au jeu et parcourez tous les mots. Le message "Le jeu vient d'être terminé" s'affiche brièvement en bas de l'écran, ce qui est normal.
Faites pivoter l'appareil ou l'émulateur. Le pain grillé s'affiche à nouveau ! Faites pivoter l'appareil plusieurs fois. Vous verrez probablement le pain grillé à chaque fois. Il s'agit d'un bug, car le pain perdu ne s'affiche qu'une seule fois, une fois le jeu terminé. Le toast doit s'afficher chaque fois que le fragment est recréé. Vous pourrez résoudre ce problème à la tâche suivante.
Étape 2: Réinitialisez l'événement terminé
Généralement, LiveData
ne transmet les mises à jour aux observateurs que lorsque les données changent. Il existe toutefois une exception à ce comportement : les observateurs reçoivent également des mises à jour lorsqu'ils passent d'un état inactif à un état actif.
C'est pourquoi le toast terminé est déclenché de façon répétée dans votre application. Lorsque le fragment de jeu est recréé après une rotation de l'écran, il passe d'un état inactif à un état actif. L'observateur du fragment est reconnecté au ViewModel
existant et reçoit les données actuelles. La méthode gameFinished()
est déclenchée à nouveau, et le toast s'affiche.
Dans cette tâche, vous allez résoudre ce problème et afficher le toast une seule fois en réinitialisant l'indicateur eventGameFinish
dans GameViewModel
.
- Dans
GameViewModel
, ajoutez une méthodeonGameFinishComplete()
pour réinitialiser l'événement terminé dans le jeu,_eventGameFinish
.
/** Method for the game completed event **/
fun onGameFinishComplete() {
_eventGameFinish.value = false
}
- Dans
GameFragment
, à la fin degameFinished()
, appelezonGameFinishComplete()
sur l'objetviewModel
. (Laisser le code de navigation dansgameFinished()
commenté pour l'instant.)
private fun gameFinished() {
...
viewModel.onGameFinishComplete()
}
- Exécutez l'application et jouez au jeu. Parcourez tous les mots, puis modifiez l'orientation de l'écran de l'appareil. Le pain perdu n'est affiché qu'une seule fois.
- Dans
GameFragment
, dans la méthodegameFinished()
, annulez la mise en commentaire du code de navigation.
Pour annuler la mise en commentaire dans Android Studio, sélectionnez les lignes commentées et appuyez surControl+/
(Command+/
sur 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()
}
Si Android Studio vous le demande, importez androidx.navigation.fragment.NavHostFragment.findNavController
.
- Exécutez l'application et jouez au jeu. Assurez-vous que l'application accède automatiquement à l'écran du score final une fois que vous avez parcouru tous les mots.
Bien joué ! Votre application utilise LiveData
pour déclencher un événement terminé dans le jeu afin de communiquer depuis le GameViewModel
au fragment de jeu, indiquant que la liste de mots est vide. Le fragment de jeu accède ensuite au fragment de score.
Dans cette tâche, vous allez convertir le score en objet LiveData
dans le ScoreViewModel
et lui associer un observateur. Cette tâche est semblable à celle que vous avez effectuée lorsque vous avez ajouté LiveData
à GameViewModel
.
Vous devez effectuer les modifications suivantes dans ScoreViewModel
. Ainsi, toutes les données de votre application utilisent LiveData
.
- Dans
ScoreViewModel
, définissez le type de variablescore
surMutableLiveData
. Renommez-le par convention_score
et ajoutez une propriété de support.
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
get() = _score
- Dans
ScoreViewModel
, dans le blocinit
, initialisez_score
. Vous pouvez supprimer ou supprimer le journal dans le blocinit
comme vous le souhaitez.
init {
_score.value = finalScore
}
- Dans
ScoreFragment
, dansonCreateView()
, après avoir initialiséviewModel
, joignez un observateur pour le scoreLiveData
. Dans le lambda, définissez la valeur du score sur la vue textuelle du score. Supprimez le code qui attribue directement la vue Texte avec la valeur de scoreViewModel
.
Code à ajouter:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})
Code à supprimer:
binding.scoreText.text = viewModel.score.toString()
Lorsque Android Studio vous le demande, importez androidx.lifecycle.Observer
.
- Exécutez votre application et jouez au jeu. L'application devrait fonctionner comme auparavant, mais elle utilise maintenant
LiveData
et un observateur pour mettre à jour le score.
Dans cette tâche, vous allez ajouter un bouton Play Again (Rejouer) à l'écran de score et implémenter son écouteur de clics à l'aide d'un événement LiveData
. Ce bouton déclenche un événement de navigation entre l'écran de score et l'écran de jeu.
Le code de démarrage de l'application inclut le bouton Play Again (Rejouer), mais il est masqué.
- Dans
res/layout/score_fragment.xml
, pour le boutonplay_again_button
, remplacez la valeur de l'attributvisibility
parvisible
.
<Button
android:id="@+id/play_again_button"
...
android:visibility="visible"
/>
- Dans
ScoreViewModel
, ajoutez un objetLiveData
pour contenir unBoolean
appelé_eventPlayAgain
. Cet objet permet d'enregistrer l'événementLiveData
pour passer de l'écran de score à l'écran de jeu.
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
get() = _eventPlayAgain
- Dans
ScoreViewModel
, définissez les méthodes pour définir et réinitialiser l'événement,_eventPlayAgain
.
fun onPlayAgain() {
_eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
_eventPlayAgain.value = false
}
- Dans
ScoreFragment
, ajoutez un observateur poureventPlayAgain
. Placez le code à la fin deonCreateView()
, avant l'instructionreturn
. Dans le lambda, revenez à l'écran du jeu et réinitialisezeventPlayAgain
.
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
if (playAgain) {
findNavController().navigate(ScoreFragmentDirections.actionRestart())
viewModel.onPlayAgainComplete()
}
})
Importez androidx.navigation.fragment.findNavController
lorsque vous y êtes invité par Android Studio.
- Dans
ScoreFragment
, dansonCreateView()
, ajoutez un écouteur de clics au bouton PlayAgain et appelezviewModel
.onPlayAgain()
.
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }
- Exécutez votre application et jouez au jeu. Une fois le jeu terminé, l'écran du score indique le score final et le bouton Play Again (Rejouer). Appuyez sur le bouton PlayAgain (Rejouer), et l'application affiche l'écran du jeu afin que vous puissiez continuer à y jouer.
Bravo ! Vous avez modifié l'architecture de votre application pour utiliser des objets LiveData
dans le ViewModel
, et vous avez associé des observateurs aux objets LiveData
. LiveData
informe les objets observateur lorsque la valeur retenue par LiveData
change.
Projet Android Studio: GuessTheWord
LiveData
LiveData
est une classe de conteneur de données observable qui tient compte du cycle de vie, l'un des composants d'architecture Android.- Vous pouvez utiliser
LiveData
pour activer la mise à jour automatique de votre interface utilisateur lorsque les données sont mises à jour. - L'objet
LiveData
est observable, ce qui signifie qu'un observateur comme une activité ou un fragment peut être averti lorsque les données détenues par l'objetLiveData
sont modifiées. LiveData
contient des données. Il s'agit d'un wrapper qui peut être utilisé avec toutes les données.LiveData
tient compte du cycle de vie, c'est-à-dire qu'il ne met à jour que les observateurs qui sont actifs dans leur cycle de vie (STARTED
ouRESUMED
, par exemple).
Ajouter LiveData
- Modifiez le type des variables de données dans
ViewModel
enLiveData
ouMutableLiveData
.
MutableLiveData
est un objet LiveData
dont la valeur peut être modifiée. MutableLiveData
est une classe générique. Vous devez donc spécifier le type de données qu'elle contient.
- Pour modifier la valeur des données détenues par le
LiveData
, utilisez la méthodesetValue()
sur la variableLiveData
.
Pour encapsuler LiveData
- Vous pouvez modifier le
LiveData
dans leViewModel
. En dehors deViewModel
, le champLiveData
doit être lisible. Vous pouvez l'implémenter à l'aide d'une propriété de support Kotlin. - Une propriété de sauvegarde Kotlin vous permet de renvoyer quelque chose d'un getter autre que l'objet exact.
- Pour encapsuler la
LiveData
, utilisezprivate
MutableLiveData
dans leViewModel
et renvoyez une propriété de supportLiveData
en dehors deViewModel
.
Données observables en direct
LiveData
suit un modèle d'observateur. L'observable est l'objetLiveData
, et les observateurs sont les méthodes des contrôleurs de l'interface utilisateur, comme les fragments. Chaque fois que les données encapsulées dansLiveData
changent, les méthodes d'observation des contrôleurs de l'interface utilisateur sont alertées.- Pour que l'observateur
LiveData
soit observable, associez un objet observateur à la référenceLiveData
dans les observateurs (comme les activités et les fragments) à l'aide de la méthodeobserve()
. - Ce modèle d'observateur
LiveData
peut être utilisé pour communiquer depuis lesViewModel
vers les contrôleurs de l'interface utilisateur.
Cours Udacity:
Documentation pour les développeurs Android:
- Présentation de ViewModel
- Présentation de LiveData
MutableLiveData
- Guide de l'architecture des applications
Autre :
- Propriété de sauvegarde dans Kotlin
Cette section répertorie les devoirs possibles pour les élèves qui effectuent cet atelier de programmation dans le cadre d'un cours animé par un enseignant. C'est à l'enseignant de procéder comme suit:
- Si nécessaire, rendez-les.
- Communiquez aux élèves comment rendre leurs devoirs.
- Notez les devoirs.
Les enseignants peuvent utiliser ces suggestions autant qu'ils le souhaitent, et ils n'ont pas besoin d'attribuer les devoirs de leur choix.
Si vous suivez vous-même cet atelier de programmation, n'hésitez pas à utiliser ces devoirs pour tester vos connaissances.
Répondez à ces questions.
Question 1
Comment encapsuler le LiveData
stocké dans un ViewModel
pour que les objets externes puissent lire les données sans pouvoir le mettre à jour ?
- Dans l'objet
ViewModel
, indiquez le type de donnéesprivate
LiveData
. Utilisez une propriété de support pour exposer les données en lecture seule de typeMutableLiveData
. - Dans l'objet
ViewModel
, indiquez le type de donnéesprivate
MutableLiveData
. Utilisez une propriété de support pour exposer les données en lecture seule de typeLiveData
. - Dans le contrôleur d'interface utilisateur, remplacez le type de données par
private
MutableLiveData
. Utilisez une propriété de support pour exposer les données en lecture seule de typeLiveData
. - Dans l'objet
ViewModel
, indiquez le type de donnéesLiveData
. Utilisez une propriété de support pour exposer les données en lecture seule de typeLiveData
.
Question 2
LiveData
met à jour un contrôleur d'interface utilisateur (un fragment, par exemple) dans un des états suivants ?
- A repris
- En arrière-plan
- En veille
- Stopped
Question 3
Dans le modèle observateur LiveData
, qu'est-ce que l'élément observable (ce qui est observé) ?
- La méthode d'observation
- Les données d'un objet
LiveData
- Contrôleur d'interface utilisateur
- L'objet
ViewModel
Démarrez la leçon suivante :
Pour obtenir des liens vers d'autres ateliers de programmation dans ce cours, consultez la page de destination des ateliers de programmation Android Kotlin Fundamentals.