LiveData

Последнее обновление: 16.04.2024

Компонент LiveData представляет еще один способ управления дангными в ViewModel и может использоваться в качестве обертки для данных во ViewModel. После помещения в LiveData данные становятся доступными для компонентов внутри класса Activity. Объекты LiveData можно объявить как изменяемые с помощью класса MutableLiveData, что позволяет функциям ViewModel вносить изменения в базовые значения данных.

Для работы с LiveData в файле libs.versions.toml в секции [libraries] укажем саму библиотеку, а в секции [versions] укажем версию этой библиотеки:

[versions]
runtimeLivedata = "1.6.5"
.......................


[libraries]
androidx-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata", version.ref = "runtimeLivedata" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" }
....................

Далее в секции [versions] укажем версию этой библиотеки:

[versions]
..................
roomRuntime = "2.6.1"

Затем в файл build.grade.kts добавим соответствующую зависимость:

То есть в итоге получится

dependencies {

    implementation (libs.androidx.runtime.livedata)
    implementation(libs.androidx.lifecycle.viewmodel.compose)

    implementation(libs.androidx.core.ktx)
    // остальные зависимости
    ........................................

}

Пример ViewModel, которая использует LiveData:

class LiveCounterViewModel : ViewModel() {
    var count: MutableLiveData<Int> = MutableLiveData(0)
    fun increase() {
        count.value = count.value!! + 1
    }
}

Здесь у нас есть переменная count, которая представляет тип MutableLiveData<Int> - обертку над числом. И есть функция increase, которая увеличивает значение в count. Поскольку теоретически значение в MutableLiveData может представлять null, однако в нашем случае это невозможная ситуация, так как значение в любом случае представляет некоторое число, то при увеличении с помощью оператора !! говорим, что это значение не равно null.

Так, перепишем прошлый пример, использовав LiveData:

package com.example.helloapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewmodel.compose.viewModel


class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            CounterView()
        }
    }
}
class LiveCounterViewModel : ViewModel() {
    var count: MutableLiveData<Int> = MutableLiveData(0)
    fun increase() {
        count.value = count.value!! + 1
    }
}

@Composable
fun CounterView(vm: LiveCounterViewModel = viewModel()) {
    val countValue by vm.count.observeAsState(0)

    Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
        Text("Count: ${countValue}", Modifier.padding(10.dp), fontSize = 25.sp)

        Button(onClick = {vm.increase()}) {
            Text(text = "Increase", fontSize = 25.sp)
        }
    }
}

Здесь определен компонент верхнего уровня CounterView, который инкапсулирует весь остальной интерфейс. В этот компонент в качестве параметра передается объект LiveCounterViewModel - наш ViewModel, который определяет состояние - переменную count и функцию increase для изменения этого состояния. Причем для создания CounterViewModel применяется не его конструктор, а функция viewModel(). Если экземпляр ViewModel (в нашем случае LiveCounterViewModel) уже создан в текущем контексте, то функция viewModel() вернет ссылку на этот экземпляр. В противном случае будет создан и возвращен новый экземпляр ViewModel.

Для отслеживания изменения значения в LiveData компонент определяет дополнительную переменную countValue:

val countValue by vm.count.observeAsState(0)

Вызов функции observeAsState() преобразует значение из LiveData в объект состояния и присваивает его переменной countValue. После преобразования это состояние будет отслеживать, и при его изменении будет запускаться рекомпозиция при компонента.

Внутри CounterView определяем текстовую метку, которая выводит состояние, и кнопку, которая вызывает функцию increase. Таким образом, при нажатии на кнопку произойдет вызов функции increase, которая, в свою очередь, увеличивает состояние count. Это изменение состояния вызывает рекомпозицию пользовательского интерфейса, в результате чего новое значение count отобразится в компоненте Text:

Управление состоянием ViewModel и LiveData в Jetpack Compose на Kotlin на Android
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850