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()
}
結果は先程と同じです。
Comment