State and Jetpack Compose

Posted by kwmt27 on Sat, Mar 6, 2021

はじめに

基本的には、書きを参考に自分なりにまとめたものです。

State

Composeでは状態をStateというもので扱います。

外から変更可能な MutableStateと外からは変更できないStateがあります。

@Stable
interface MutableState<T> : State<T> {
    override var value: T
    operator fun component1(): T
    operator fun component2(): (T) -> Unit
}
@Stable
interface State<T> {
    val value: T
}
var expanded by remember { mutableStateOf(false) }

mutableStateOfで新しいBooleanのStateを作成しています。

Buttonのクリックイベントの中でその値を変更しています。

onClick = { expanded = true }

Stateを使っている箇所が再描画されます。

Composable関数は必要に応じて再実行されます。これをrecomposition(再構成) とよびます。

stateを宣言する時、

by はKotlinのデリゲートプロパティという機能。

byを使わず =を使うこともできますが、expanded.value = trueのように.valueをつける必要があります。

var expanded = remember { mutableStateOf(false) }
remember

rememberもComposable関数です.

指定したラムダを実行した計算結果を覚えておくための関数です。

Composable関数が再実行される可能性があり、 rembemrを使わず mutableStateOfだけでStateを宣言した場合、 再実行されるときに最初期化され、状態が失われてしまうことになります。 その状態を保持するためにrememberを付ける必要があります。

例 Expanding Card

@Composable
fun ExpandingCard(title: String, body: String) {
   var expanded by remember { mutableStateOf(false) }

   Card {
       Column(
           Modifier
               .width(280.dp)
               .animateContentSize()
               .padding(top = 16.dp, start = 16.dp, end = 16.dp)
       ) {
           Text(text = title)
           if (expanded) {
               Text(text = body, Modifier.padding(top = 8.dp))
               IconButton(onClick = { expanded = false }, modifier = Modifier.fillMaxWidth()) {
                   Icon(Icons.Default.MoreVert, contentDescription = null)
               }
           } else {
               IconButton(onClick = { expanded = true }, modifier = Modifier.fillMaxWidth()) {
                   Icon(Icons.Default.Face, contentDescription = null)
               }
           }
       }
   }
}

これをPreviewすると

@Composable
@Preview
fun PreviewExpandingCard() {
    ExpandingCard("hello", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
}

次のような動きになります。



comments powered by Disqus