Домой Android разработкаJava, Kotlin и Android SDK ViewModel и LiveData. Примеры использования.

ViewModel и LiveData. Примеры использования.

by dilix
Android Viewmodel Livedata

Архитектура Android приложений подразумевает сохранение и восстановление состояния Activity. В этом помогают ViewModel и LiveData. Два мощных компонента, которые являются частью Android Jetpack.

Жизненный цикл Activity

Давайте для начала совсем чуть-чуть поговорим об архитектуре Activity как основном компоненте ваших Android приложений. Вероятно вы знаете, что система может пересоздавать эти самые Активити. Например, когда оно в фоне и системе нужны ресурсы, или вы просто повернули экран и для необходимо пересоздать весь UI.

Activity lifecycle
Activity lifecycle

Вся сложность состоит в том, что для пользователя это не очевидно. Он вполне обоснованно предполагает, что приложение живет до тех пока не закрыто. Усугубляется это и тем, что в приложении с несколькими Activity для пользователя переходы между активностями не заметны. При переходе «назад» без сохранения состояния мы увидим не то что ожидаем, а начальное состояние.

Отсюда возникает необходимость хранить некое состояние — будь то загруженные данные или текущие переменные. Для этого и создан ViewModel. А для передачи информации — LiveData. Вот о них и поговорим.

Android ViewModel

ViewModel создан для того, чтобы хранить и управлять данными, которые относятся к UI (в нашем случае, например к Activity), но с учетом lifecycle. Т.е. он переживает и пересоздание всего компонента. Это хорошо видно на картинке:

Illustrates the lifecycle of a ViewModel as an activity changes state.
ViewModel lifecycle

ViewModel без контекста

В самом простом (и по сути правильном) варианте ViewModel создается путем наследования от класса ViewModel

class MyViewModel : ViewModel()...

Получить доступ к созданной ViewModel можно одной строчкой в вашей Activity или Fragment

val model: MyViewModel by viewModels()

ViewModel с доступом к контексту

Если вам нужен доступ к контексту приложения, то существует реализация AndroidViewModel. Но я рекомендую стараться использовать базовый ViewModel в котором нет контекста. Так архитектура получается более консистентная и простая.


Shared ViewModel

ViewModel можно использовать для взаимодействия между двумя фрагментами. Т.е. использовать одну разделяемую модель данных.

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}

class DetailFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
            // Update the UI
        })
    }
}

Забегая вперед хочу сказать, что делать я бы так не советовал. Я пробовал 🙂 В итоге shared ViewModel становится довольно громоздкой и рискует превратится в God object. Лучше разделить модели относительно экранов, а общие данные хранить ниже — на уровне Repository.

Теперь рассмотрим как передавать данные из ViewModel непосредственно в ваши View.

Android LiveData

Для передачи данных из ViewModel в Android Jetpack также есть LiveData. Это объект с данным, которые предоставляет доступ к информации в потоковом режиме (observable). Если вы знакомы с rx, то найдете много общего по замыслу. Важное различие в том, что LiveData учитывает Lifecycle того, в чьем контексте работает. Другими словами закрывать его принудительно руками не нужно.

Для использования LiveData достаточно объявить её в вашей ViewModel.

class NameViewModel : ViewModel() {

    // Create a LiveData with a String
    val currentName: MutableLiveData<String> by lazy {
        MutableLiveData<String>()
    }

    // Rest of the ViewModel...
}

Теперь внутри Activity, где хотите «слушать» данные устанавливаем observer.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Other code to setup the activity...

        // Create the observer which updates the UI.
        val nameObserver = Observer<String> { newName ->
            // Update the UI, in this case, a TextView.
            nameTextView.text = newName
        }

        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        model.currentName.observe(this, nameObserver)
    }

Теперь вы на базовом уровне знаете как использовать и для чего нужны ViewModel и LiveData.

Кстати, Google в рамках Android Jetpack представил много интересных инструментов, не только эти два. И да, я уже рассказывал про полезные библиотеки для Android разработчика.

Хочешь обсудить Android разработку?
Заходи к нам Вконтакте, на Facebook и в Телеграм!

Добавить комментарий

Может быть интересно

Этот сайт использует Cookie файлы для улучшения вашего пользовательского взаимодействия. Используя данный сайт вы соглашается с этим. Принять Читать

Политика конфиденциальности и Cookies