Эта практическая работа входит в курс «Основы Android Kotlin». Вы получите максимальную пользу от этого курса, если будете выполнять практические работы последовательно. Все практические работы курса перечислены на целевой странице практической работы «Основы Android Kotlin» .
Введение
В предыдущей лабораторной работе вы использовали ViewModel в приложении GuessTheWord, чтобы данные приложения сохранялись при изменении конфигурации устройства. В этой лабораторной работе вы узнаете, как интегрировать LiveData с данными в классах ViewModel . LiveData , один из компонентов архитектуры Android , позволяет создавать объекты данных, которые уведомляют представления об изменениях в базовой базе данных.
Чтобы использовать класс LiveData , необходимо настроить «наблюдатели» (например, действия или фрагменты), которые отслеживают изменения данных приложения. LiveData учитывает жизненный цикл, поэтому обновляет только наблюдателей компонентов приложения, находящихся в активном состоянии жизненного цикла.
Что вам уже следует знать
- Как создавать простые приложения для Android на Kotlin.
- Как перемещаться между пунктами назначения вашего приложения.
- Жизненный цикл активности и фрагмента.
- Как использовать объекты
ViewModelв вашем приложении. - Как создавать объекты
ViewModelс помощью интерфейсаViewModelProvider.Factory.
Чему вы научитесь
- Что делает объекты
LiveDataполезными. - Как добавить
LiveDataк данным, хранящимся вViewModel. - Когда и как использовать
MutableLiveData. - Как добавить методы наблюдателя для наблюдения за изменениями в
LiveData. - Как инкапсулировать
LiveDataс помощью резервного свойства. - Как организовать взаимодействие между контроллером пользовательского интерфейса и соответствующей ему
ViewModel.
Что ты будешь делать?
- Используйте
LiveDataдля определения слова и оценки в приложении GuessTheWord. - Добавьте наблюдателей, которые заметят, когда изменится слово или счет.
- Обновите текстовые представления, отображающие измененные значения.
- Используйте шаблон наблюдателя
LiveDataдля добавления события завершения игры. - Реализуйте кнопку «Воспроизвести снова» .
В практических занятиях по коду Урока 5 вы разработаете приложение GuessTheWord, начав с базового кода. GuessTheWord — это игра в стиле шарады для двух игроков, где игроки объединяют усилия, чтобы набрать как можно больше очков.
Первый игрок смотрит на слова в приложении и по очереди разыгрывает каждое слово, не показывая его второму игроку. Второй игрок пытается угадать слово.
Чтобы начать игру, первый игрок открывает приложение на устройстве и видит слово, например, «гитара», как показано на снимке экрана ниже.
Первый игрок изображает слово, стараясь не произносить его целиком.
- Когда второй игрок правильно отгадывает слово, первый игрок нажимает кнопку « Понял» , что увеличивает счет на единицу и показывает следующее слово.
- Если второй игрок не может угадать слово, первый игрок нажимает кнопку «Пропустить» , что уменьшает счет на единицу и переходит к следующему слову.
- Чтобы завершить игру, нажмите кнопку «Завершить игру» . (Эта функция отсутствует в стартовом коде первой лабораторной работы в серии.)
В этой лабораторной работе вы улучшите приложение GuessTheWord, добавив событие завершения игры, когда пользователь циклически перебирает все слова в приложении. Вы также добавите кнопку «Играть снова» во фрагмент с результатами, чтобы пользователь мог сыграть в игру ещё раз.
Титульный экран |
Игровой экран |
Экран результатов |
В этом задании вам предстоит найти и запустить стартовый код для этой лабораторной работы. В качестве стартового кода вы можете использовать приложение GuessTheWord, созданное в предыдущей лабораторной работе, или скачать готовое стартовое приложение.
- (Необязательно) Если вы не используете код из предыдущей лабораторной работы, скачайте начальный код для этой. Распакуйте код и откройте проект в Android Studio.
- Запустите приложение и играйте в игру.
- Обратите внимание, что кнопка «Пропустить» отображает следующее слово и уменьшает счёт на один, а кнопка « Понял» отображает следующее слово и увеличивает счёт на один. Кнопка «Завершить игру» завершает игру.
LiveData — это класс-хранилище наблюдаемых данных, учитывающий жизненный цикл. Например, вы можете обернуть LiveData вокруг текущего счёта в приложении GuessTheWord. В этой практической работе вы узнаете о нескольких характеристиках LiveData :
-
LiveDataявляется наблюдаемым, что означает, что наблюдатель уведомляется об изменении данных, хранящихся в объектеLiveData. -
LiveDataхранит данные;LiveData— это оболочка, которую можно использовать с любыми данными. -
LiveDataучитывает жизненный цикл, то есть обновляет только наблюдателей, находящихся в активном состоянии жизненного цикла, напримерSTARTEDилиRESUMED.
В этом задании вы научитесь обертывать любые типы данных в объекты LiveData , преобразуя текущие данные о счёте и слове в GameViewModel в LiveData . В следующем задании вы добавите наблюдателя к этим объектам LiveData и научитесь наблюдать LiveData .
Шаг 1: Измените счет и слово, чтобы использовать LiveData
- В пакете
screens/gameоткройте файлGameViewModel. - Измените тип переменных
scoreиwordнаMutableLiveData.
MutableLiveData— это классLiveData, значение которого можно изменять.MutableLiveData— это универсальный класс, поэтому необходимо указать тип хранимых им данных.
// The current word
val word = MutableLiveData<String>()
// The current score
val score = MutableLiveData<Int>()- В
GameViewModel, внутри блокаinit, инициализируйтеscoreиword. Чтобы изменить значение переменнойLiveData, используйте методsetValue(). В Kotlin методsetValue()можно вызвать, используя свойствоvalue.
init {
word.value = ""
score.value = 0
...
}Шаг 2: Обновите ссылку на объект LiveData
Переменные score и word теперь имеют тип LiveData . На этом этапе вы изменяете ссылки на эти переменные, используя свойство value .
- В методе
onSkip()вGameViewModelизменитеscoreнаscore.value. Обратите внимание на ошибку о возможномscoreвnull. Эту ошибку нужно исправить следующим способом. - Чтобы устранить ошибку, добавьте проверку
nullвscore.valueвonSkip(). Затем вызовите функциюminus()дляscore, которая выполнит вычитание с защитойnull.
fun onSkip() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.minus(1)
}
nextWord()
}- Обновите метод
onCorrect()таким же образом: добавьте проверкуnullк переменнойscoreи используйте функциюplus().
fun onCorrect() {
if (!wordList.isEmpty()) {
score.value = (score.value)?.plus(1)
}
nextWord()
}- В
GameViewModelвнутри методаnextWord()измените ссылкуwordнаword.value.
private fun nextWord() {
if (!wordList.isEmpty()) {
//Select and remove a word from the list
word.value = wordList.removeAt(0)
}
}-
value.GameFragmentвнутри методаupdateWordText()..viewModelwordviewModel.word
/** Methods for updating the UI **/
private fun updateWordText() {
binding.wordText.text = viewModel.word.value
}- В
GameFragment, внутри методаupdateScoreText(), измените ссылку.viewModel.scoreнаviewModel.scorevalue.
private fun updateScoreText() {
binding.scoreText.text = viewModel.score.value.toString()
}- В методе
gameFinished()..scoreGameFragmentссылкуviewModelnullviewModel.Добавьте обязательную проверкуscorevalue.
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)
}- Убедитесь, что в вашем коде нет ошибок. Скомпилируйте и запустите приложение. Функциональность приложения должна остаться прежней.
Эта задача тесно связана с предыдущей, где вы преобразовали данные о счёте и словах в объекты LiveData . В этой задаче вы прикрепляете объекты Observer к этим объектам LiveData .
- В методе
GameFragment,onCreateView()присоедините объектObserverк объектуLiveDataдля текущего счётаviewModel.score. Используйте методobserve()и поместите код после инициализацииviewModel. Для упрощения кода используйте лямбда-выражение. ( Лямбда-выражение — это анонимная функция, которая не объявляется, а передаётся непосредственно как выражение.)
viewModel.score.observe(this, Observer { newScore ->
}) Разрешите ссылку на Observer . Для этого выберите Observer , нажмите Alt+Enter ( Option+Enter на Mac) и импортируйте androidx.lifecycle.Observer .
- Наблюдатель, который вы только что создали, получает событие при изменении данных, хранящихся в наблюдаемом объекте
LiveData. Внутри наблюдателя обновитеTextViewсчёта, указав новый счёт.
/** Setting up LiveData observation relationship **/
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})- Прикрепите объект
Observerк текущему объектуLiveDataслова. Сделайте это так же, как вы прикрепили объектObserverк текущему счёту.
/** Setting up LiveData observation relationship **/
viewModel.word.observe(this, Observer { newWord ->
binding.wordText.text = newWord
})При изменении значения score или word score или word , отображаемые на экране, теперь обновляются автоматически.
- В
GameFragmentудалите методыupdateWordText()иupdateScoreText()и все ссылки на них. Они вам больше не понадобятся, поскольку текстовые представления обновляются методами наблюдателяLiveData. - Запустите приложение. Ваше игровое приложение должно работать точно так же, как и раньше, но теперь оно использует
LiveDataи наблюдателейLiveData.
Инкапсуляция — это способ ограничить прямой доступ к некоторым полям объекта. Инкапсуляция объекта предоставляет набор публичных методов, которые изменяют его внутренние поля. Инкапсуляция позволяет контролировать, как другие классы манипулируют этими внутренними полями.
В вашем текущем коде любой внешний класс может изменять переменные score и word , используя свойство value , например, viewModel.score.value . В приложении, которое вы разрабатываете в этой лабораторной работе, это может не иметь значения, но в рабочем приложении вам нужен контроль над данными в объектах ViewModel .
Только ViewModel должна редактировать данные в вашем приложении. Но UI-контроллерам необходимо читать данные, поэтому поля данных не могут быть полностью приватными. Для инкапсуляции данных вашего приложения используются объекты MutableLiveData и LiveData .
MutableLiveData против LiveData :
- Данные в объекте
MutableLiveData, как следует из названия, можно изменять. ВнутриViewModelданные должны быть доступны для редактирования, поэтому используетсяMutableLiveData. - Данные в объекте
LiveDataможно читать, но нельзя изменять. ИзвнеViewModelданные должны быть доступны для чтения, но не для редактирования, поэтому они должны быть представлены какLiveData.
Для реализации этой стратегии используется резервное свойство Kotlin. Резервное свойство позволяет возвращать из геттера нечто, отличное от точного объекта. В этой задаче вы реализуете резервное свойство для объектов score и word в приложении GuessTheWord.
Добавить свойство поддержки к партитуре и слову
- В
GameViewModelсделайте текущий объектscoreprivate. - Чтобы следовать соглашению об именовании, используемому в резервных свойствах, измените
scoreна_score. Свойство_scoreтеперь представляет собой изменяемую версию игрового счёта для внутреннего использования. - Создайте публичную версию типа
LiveDataпод названиемscore.
// The current score
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>- Вы видите ошибку инициализации. Эта ошибка возникает, потому что внутри
GameFragmentscoreявляется ссылкойLiveData, иscoreбольше не может получить доступ к своему сеттеру. Подробнее о геттерах и сеттерах в Kotlin см. в разделе Геттеры и сеттеры .
Чтобы устранить ошибку, переопределите методget()для объектаscoreвGameViewModelи верните резервное свойство_score.
val score: LiveData<Int>
get() = _score- В
GameViewModelизмените ссылкиscoreна его внутреннюю изменяемую версию_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)
}
...
}- Переименуйте объект
wordв_wordи добавьте для него резервное свойство, как вы это делали для объектаscore.
// 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)
}
}Отличная работа, вы инкапсулировали объекты LiveData word и score .
Ваше текущее приложение переходит на экран счёта, когда пользователь нажимает кнопку « Завершить игру» . Вы также хотите, чтобы приложение переходило на экран счёта, когда игроки циклически повторяют все слова. После того, как игроки закончат с последним словом, игра должна автоматически завершаться, чтобы пользователю не приходилось нажимать кнопку.
Для реализации этой функциональности необходимо, чтобы событие из ViewModel было инициировано и передано фрагменту после отображения всех слов. Для этого используется шаблон наблюдателя LiveData для моделирования события завершения игры.
Модель наблюдателя
Паттерн «Наблюдатель» — это шаблон проектирования программного обеспечения. Он определяет взаимодействие между объектами: наблюдаемым («субъектом» наблюдения) и наблюдателями . Наблюдаемый — это объект, уведомляющий наблюдателей об изменениях своего состояния.

В случае LiveData в этом приложении наблюдаемым объектом (субъектом) является объект LiveData , а наблюдателями — методы в контроллерах пользовательского интерфейса, например, фрагментах. Изменение состояния происходит при каждом изменении данных, обёрнутых в LiveData . Классы LiveData играют ключевую роль в обмене данными между ViewModel и фрагментом.
Шаг 1: Используйте LiveData для обнаружения события завершения игры
В этой задаче вы используете шаблон наблюдателя LiveData для моделирования события завершения игры.
- В
GameViewModelсоздайте объектBooleanMutableLiveDataс именем_eventGameFinish. Этот объект будет хранить событие завершения игры. - После инициализации объекта
_eventGameFinishсоздайте и инициализируйте резервное свойство с именемeventGameFinish.
// Event which triggers the end of the game
private val _eventGameFinish = MutableLiveData<Boolean>()
val eventGameFinish: LiveData<Boolean>
get() = _eventGameFinish- В
GameViewModelдобавьте методonGameFinish(). В этом методе установите для события завершения игрыeventGameFinishзначениеtrue.
/** Method for the game completed event **/
fun onGameFinish() {
_eventGameFinish.value = true
}- В
GameViewModelвнутри методаnextWord()завершите игру, если список слов пуст.
private fun nextWord() {
if (wordList.isEmpty()) {
onGameFinish()
} else {
//Select and remove a _word from the list
_word.value = wordList.removeAt(0)
}
}- В
GameFragment, внутриonCreateView(), после инициализацииviewModel, присоедините наблюдателя кeventGameFinish. Используйте методobserve(). Внутри лямбда-функции вызовите методgameFinished().
// Observer for the Game finished event
viewModel.eventGameFinish.observe(this, Observer<Boolean> { hasFinished ->
if (hasFinished) gameFinished()
})- Запустите приложение, сыграйте в игру и пройдите все слова. Приложение автоматически перейдет к экрану счёта, а не останется в игровом фрагменте, пока вы не нажмёте «Завершить игру» .
После того, как список слов опустеет, устанавливаетсяeventGameFinish, вызывается связанный метод наблюдателя в игровом фрагменте, и приложение переходит к фрагменту экрана. - Добавленный вами код создал проблему жизненного цикла. Чтобы разобраться в проблеме, закомментируйте код навигации в методе
gameFinished()классаGameFragment. Убедитесь, что в методе сохраненоToastсообщение.
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)
}
- Запустите приложение, играйте и пройдитесь по всем словам. В нижней части игрового экрана на короткое время появится всплывающее сообщение «Игра только что завершена», что вполне ожидаемо.
Теперь поверните устройство или эмулятор. Уведомление снова появится! Поверните устройство ещё несколько раз, и, вероятно, вы будете видеть уведомление каждый раз. Это ошибка, поскольку уведомление должно появляться только один раз, после завершения игры. Уведомление не должно появляться каждый раз при пересоздании фрагмента. Вы решите эту проблему в следующем задании.
|
|
Шаг 2: Сброс события завершения игры
Обычно LiveData отправляет обновления наблюдателям только при изменении данных. Исключением из этого правила является то, что наблюдатели также получают обновления при переходе из неактивного состояния в активное.
Именно поэтому уведомление о завершении игры постоянно запускается в вашем приложении. Когда фрагмент игры пересоздаётся после поворота экрана, он переходит из неактивного состояния в активное. Наблюдатель во фрагменте повторно подключается к существующей ViewModel и получает текущие данные. Метод gameFinished() запускается повторно, и уведомление отображается.
В этой задаче вы исправите эту проблему и отобразите уведомление только один раз, сбросив флаг eventGameFinish в GameViewModel .
- В
GameViewModelдобавьте методonGameFinishComplete()для сброса события завершения игры,_eventGameFinish.
/** Method for the game completed event **/
fun onGameFinishComplete() {
_eventGameFinish.value = false
}- В
GameFragment, в концеgameFinished(), вызовитеonGameFinishComplete()для объектаviewModel. (Пока оставьте код навигации вgameFinished()закомментированным.)
private fun gameFinished() {
...
viewModel.onGameFinishComplete()
}- Запустите приложение и играйте. Прочитайте все слова, а затем измените ориентацию экрана устройства. Уведомление отображается только один раз.
- В
GameFragmentвнутри методаgameFinished()раскомментируйте код навигации.
Чтобы раскомментировать строки в Android Studio, выделите закомментированные строки и нажмитеControl+/(Command+/на 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()
}Если Android Studio предложит, импортируйте androidx.navigation.fragment.NavHostFragment.findNavController .
- Запустите приложение и играйте. Убедитесь, что приложение автоматически перейдёт на экран с итоговым счётом после того, как вы разгадаете все слова.
|
|
Отличная работа! Ваше приложение использует LiveData для активации события завершения игры, чтобы сообщить GameViewModel фрагменту игры о том, что список слов пуст. Затем фрагмент игры переходит к фрагменту счёта.
В этой задаче вы преобразуете счёт в объект LiveData в ScoreViewModel и присоединяете к нему наблюдателя. Эта задача аналогична той, что вы выполняли при добавлении LiveData в GameViewModel .
Эти изменения вносятся в ScoreViewModel для полноты картины, чтобы все данные в вашем приложении использовали LiveData .
- В
ScoreViewModelизмените тип переменнойscoreнаMutableLiveData. Переименуйте её по соглашению в_scoreи добавьте резервное свойство.
private val _score = MutableLiveData<Int>()
val score: LiveData<Int>
get() = _score- В
ScoreViewModel, внутри блокаinit, инициализируйте_score. Вы можете удалить или оставить журнал в блокеinitпо своему усмотрению.
init {
_score.value = finalScore
}- В
ScoreFragmentвнутриonCreateView()после инициализацииviewModelприсоедините наблюдателя для объектаLiveDataсо счётом. Внутри лямбда-выражения установите значение счёта в текстовом представлении счёта. Удалите код, который напрямую присваивает текстовому представлению значение счёта изViewModel.
Код для добавления:
// Add observer for score
viewModel.score.observe(this, Observer { newScore ->
binding.scoreText.text = newScore.toString()
})Код для удаления:
binding.scoreText.text = viewModel.score.toString()При появлении запроса от Android Studio импортируйте androidx.lifecycle.Observer .
- Запустите приложение и играйте. Приложение должно работать как и прежде, но теперь оно использует
LiveDataи наблюдателя для обновления счёта.
В этой задаче вы добавите кнопку «Играть снова» на экран счёта и реализуете её прослушиватель кликов с помощью события LiveData . Кнопка запускает событие для перехода с экрана счёта на экран игры.
Стартовый код приложения включает кнопку «Воспроизвести снова» , но она скрыта.
- В
res/layout/score_fragment.xmlдля кнопкиplay_again_buttonизмените значение атрибутаvisibilityнаvisible.
<Button
android:id="@+id/play_again_button"
...
android:visibility="visible"
/>- В
ScoreViewModelдобавьте объектLiveDataдля храненияBoolean_eventPlayAgain. Этот объект используется для сохранения событияLiveDataдля перехода с экрана счёта на экран игры.
private val _eventPlayAgain = MutableLiveData<Boolean>()
val eventPlayAgain: LiveData<Boolean>
get() = _eventPlayAgain- В
ScoreViewModelопределите методы для установки и сброса события_eventPlayAgain.
fun onPlayAgain() {
_eventPlayAgain.value = true
}
fun onPlayAgainComplete() {
_eventPlayAgain.value = false
}- В
ScoreFragmentдобавьте наблюдателя дляeventPlayAgain. Поместите код в конецonCreateView(), перед операторомreturn. Внутри лямбда-выражения вернитесь на игровой экран и сбросьтеeventPlayAgain.
// Navigates back to game when button is pressed
viewModel.eventPlayAgain.observe(this, Observer { playAgain ->
if (playAgain) {
findNavController().navigate(ScoreFragmentDirections.actionRestart())
viewModel.onPlayAgainComplete()
}
})Импортируйте androidx.navigation.fragment.findNavController по запросу Android Studio.
- В
ScoreFragmentвнутриonCreateView()добавьте прослушиватель щелчков для кнопки PlayAgain и вызовитеviewModel.onPlayAgain().
binding.playAgainButton.setOnClickListener { viewModel.onPlayAgain() }- Запустите приложение и играйте. После завершения игры на экране счёта отобразится итоговый счёт и кнопка « Играть снова» . Нажмите кнопку «Играть снова» , и приложение перейдёт на экран игры, чтобы вы могли сыграть ещё раз.

Отличная работа! Вы изменили архитектуру своего приложения для использования объектов LiveData в ViewModel и прикрепили наблюдателей к объектам LiveData . LiveData уведомляет объекты-наблюдатели об изменении значения, хранящегося в LiveData .
Проект Android Studio: GuessTheWord
LiveData
-
LiveData— это класс хранилища наблюдаемых данных, учитывающий жизненный цикл, один из компонентов архитектуры Android . - Вы можете использовать
LiveData, чтобы ваш пользовательский интерфейс автоматически обновлялся при обновлении данных. -
LiveDataявляется наблюдаемым, что означает, что наблюдатель, такой как активность или фрагмент, может быть уведомлен об изменении данных, хранящихся в объектеLiveData. -
LiveDataхранит данные; это оболочка, которую можно использовать с любыми данными. -
LiveDataучитывает жизненный цикл, то есть обновляет только наблюдателей, находящихся в активном состоянии жизненного цикла, напримерSTARTEDилиRESUMED.
Чтобы добавить LiveData
- Измените тип переменных данных в
ViewModelнаLiveDataилиMutableLiveData.
MutableLiveData — это объект LiveData , значение которого можно изменить. MutableLiveData — это универсальный класс, поэтому необходимо указать тип хранимых им данных.
- Чтобы изменить значение данных, хранящихся в
LiveData, используйте методsetValue()для переменнойLiveData.
Для инкапсуляции LiveData
-
LiveDataвнутриViewModelдолжны быть доступны для редактирования. ВнеViewModelданныеLiveDataдолжны быть доступны для чтения. Это можно реализовать с помощью резервного свойства Kotlin. - Резервное свойство Kotlin позволяет вам возвращать из геттера что-то, отличное от самого объекта.
- Чтобы инкапсулировать
LiveData, используйтеprivateMutableLiveDataвнутриViewModelи верните резервное свойствоLiveDataза пределамиViewModel.
Наблюдаемые LiveData
-
LiveDataследует шаблону наблюдателя. Наблюдаемым объектом является объектLiveData, а наблюдателями — методы в контроллерах пользовательского интерфейса, например, фрагменты. При каждом изменении данных, обёрнутых вLiveData, методы наблюдателя в контроллерах пользовательского интерфейса получают уведомление. - Чтобы сделать
LiveDataнаблюдаемым, прикрепите объект наблюдателя к ссылкеLiveDataв наблюдателях (таких как действия и фрагменты) с помощью методаobserve(). - Этот шаблон наблюдателя
LiveDataможно использовать для связи междуViewModelи контроллерами пользовательского интерфейса.
Курс Udacity:
Документация для разработчиков Android:
Другой:
- Поддержка собственности в Kotlin
В этом разделе перечислены возможные домашние задания для студентов, работающих над этой лабораторной работой в рамках курса, проводимого преподавателем. Преподаватель должен выполнить следующие действия:
- При необходимости задавайте домашнее задание.
- Объясните учащимся, как следует сдавать домашние задания.
- Оцените домашние задания.
Преподаватели могут использовать эти предложения так часто или редко, как пожелают, и могут свободно задавать любые другие домашние задания, которые они сочтут подходящими.
Если вы работаете с этой лабораторной работой самостоятельно, можете использовать эти домашние задания для проверки своих знаний.
Ответьте на эти вопросы
Вопрос 1
Как инкапсулировать LiveData хранящиеся в ViewModel , чтобы внешние объекты могли считывать данные, не имея возможности обновлять их?
- Внутри объекта
ViewModelизмените тип данных наprivateLiveData. Используйте резервное свойство, чтобы предоставить данные типаMutableLiveDataтолько для чтения. - Внутри объекта
ViewModelизмените тип данных наprivateMutableLiveData. Используйте резервное свойство, чтобы предоставить данные типаLiveDataтолько для чтения. - Внутри контроллера пользовательского интерфейса измените тип данных на
privateMutableLiveData. Используйте резервное свойство, чтобы предоставить данные типаLiveDataтолько для чтения. - Внутри объекта
ViewModelизмените тип данных наLiveData. Используйте резервное свойство, чтобы предоставить данные типаLiveDataтолько для чтения.
Вопрос 2
LiveData обновляет контроллер пользовательского интерфейса (например, фрагмент), если контроллер пользовательского интерфейса находится в каком из следующих состояний?
- Возобновлено
- На заднем плане
- Приостановлено
- Остановлено
Вопрос 3
Что является наблюдаемым элементом (что наблюдается) в шаблоне наблюдателя LiveData ?
- Метод наблюдателя
- Данные в объекте
LiveData - Контроллер пользовательского интерфейса
- Объект
ViewModel
Начните следующий урок:
Ссылки на другие практические занятия по этому курсу см. на целевой странице практических занятий по основам Android Kotlin .




