JetpackComposeでViewModelやLiveDataを使ってみた

JetpackComposeでViewModelやLive Dataを使う方法についてメモ。

アプリの実行画面

以下を実現するコードを書いてみる

・ボタンを押すとカウントアップ

・テキストフィールドに入力した文字を表示

・ボタンを押すと配列にString要素を追加。

基本的には、ViewModel中にLiveData変数を用意して、操作するメソッドを用意する。

package com.atmc118.holidayjapan

import androidx.compose.runtime.mutableStateListOf
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class SampleViewModel: ViewModel() {
    val count = MutableLiveData(0)
    val text = MutableLiveData("")
    val stringList = MutableLiveData<MutableList<String>>(mutableStateListOf())
    var counter = 0

    fun countUp() {
        val c = count.value ?: 0
        count.value = c + 1
    }

    fun textChanged(tmp:String){
        text.value = tmp
    }

    fun addDataToList() {
        counter++
        stringList.value?.add(counter.toString())
    }
}

次にUI。

@Composable
fun AppScreen(viewModel: SampleViewModel) {
    val count: Int by viewModel.count.observeAsState(0)
    val text:String by viewModel.text.observeAsState("")
    val stringList = viewModel.stringList.observeAsState()

    Column {
        Text(text = "Count: $count")
        Button(onClick = {viewModel.countUp()}) {
            Text(text = "Count up")
        }
        OutlinedTextField(
            value = text,
            onValueChange = { viewModel.textChanged(it) },
            label = { Text("Label") }
        )
        Text(text = "Text: $text")
        Button(onClick = {
            viewModel.addDataToList()
        }) {
            Text("add")
        }
        stringList.value?.forEach { str ->
            Text(str)
        }
    }
}

ViewModelのメソッドを読んだり、observeAsStateを使って変数を監視する。

observeAsStateを使うときには、Gradleに1行追加する必要がある。

implementation "androidx.compose.runtime:runtime-livedata:1.3.3"

あと、compileSdkを33以降にする。

android {
    namespace 'com.atmc118.holidayjapan'
    compileSdk 33

ViewModelのインスタンス化はonCreateで行う。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            HolidayJapanTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    AppScreen(viewModel = SampleViewModel())
                }
            }
        }
    }
}

Previewだと配列の追加がうまく動作していなかったので実機で試しました。

Enjoy! Jetpack Compose!!

ABOUTこの記事をかいた人

個人アプリ開発者。Python、Swift、Unityのことを発信します。月間2.5万PVブログ運営。 Twitter:@yamagablog