MENU

【Jetpack Compose】mutableStateで状態の変化を扱う | 値が更新されたときに画面も更新する

記事内に商品プロモーションが含まれる場合があります

JetPack Composeで次のようなボタンをカウント回数を表示するコードを準備しました。

期待する動きとしては、カウントをタップすると数字が0から順番に増えていってほしいところですが、このコードではカウントをタップしても数字が増えません。

import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun MyComposable() {
    var count:Int = 0

    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = count.toString(),
            fontSize = 24.sp,
            modifier = Modifier.padding(4.dp)
        )
        Button(
            onClick = {
                count++
            }
        )
        {
            Text(text = "カウント")
        }
    }
}

@Preview(showBackground = true, widthDp = 100)
@Composable
fun MyComposablePreview() {
    MyComposable()
}
目次

値が更新されるようにするには?

Jetpack Composeでは値が変化するもの、つまり値の状態が変化するものを扱うにはmutableStateを使う必要があります。

mutableStateとは、Composable関数内で状態を管理するための仕組みで、これを使うことにより、UIの状態が変更されると、Composable関数が再度呼び出されてUIが更新されるようになります。

つまり、変数の状態とUIが同期されることを意味します。

mutableStateの使い方

次の例のようにmutableStateOf関数を使用して、初期値を持つmutableStateを作成します。

rememberは、Composable関数内で状態を保持するためのフックで、これにより状態が保持されたまま、Composable関数が再レンダリングされることが保証されます。

import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var count = remember { mutableStateOf(0) }

値の更新方法

mutableStateの値は.valueプロパティを介して読み取り、更新します。

以下は、カウントを1つ増やす操作を行っています。

count.value++

最初のサンプルコードを書き直す

このページの最初に紹介したコードをmutableStateを使った形に書き直すと次のようになります。

import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun MyComposable() {
    var count = remember { mutableStateOf(0) }

    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = count.value.toString(),
            fontSize = 24.sp,
            modifier = Modifier.padding(4.dp)
        )
        Button(
            onClick = {
                count.value++
            }
        )
        {
            Text(text = "カウント")
        }
    }
}

@Preview(showBackground = true, widthDp = 200)
@Composable
fun MyComposablePreview() {
    MyComposable()
}

このコードで動作を確認すると、カウントボタンをタップすることで無事に値を更新することができました。

プロパティデリゲードを使った方法

先程の例では、状態(値)を取り出すのに、.valueを記述する必要がありました。

これを毎回書くのは面倒です。

それを省略する方法として、プロパティデリゲードという仕組みを使った方法もあります。

難しい言葉が出てきましたが、やり方は簡単で次のようにbyキーワードを使用します。

var count by remember { mutableStateOf(0) }

あとは、値を取り出す際に書いていた.valueを削除するだけです。

書き直したコードが次のようになります。

import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun MyComposable() {
    var count by remember { mutableStateOf(0) }

    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(
            text = count.toString(),
            fontSize = 24.sp,
            modifier = Modifier.padding(4.dp)
        )
        Button(
            onClick = {
                count++
            }
        )
        {
            Text(text = "カウント")
        }
    }
}

@Preview(showBackground = true, widthDp = 200)
@Composable
fun MyComposablePreview() {
    MyComposable()
}

結果は先程と同じです。

Share

Comment

コメントする

目次