0
0

More than 1 year has passed since last update.

AnimatedVisibilityをif文で囲んではならない

Posted at

はじめに

UI要素を表示させる時にふわっと表示するようにアニメーションさせたくてAnimatedVisibilityを使ったのですが、最初使い方がよく分からなくて間違って使ってたので備忘録としてまとめておきます。

AnimatedVisibilityをif文で囲むとアニメーションしなくなる

通常フラグがtrueの場合のみComposableを表示したい場合は以下のように書きますよね。

@Composable
fun AnimatedScreen(
    modifier: Modifier = Modifier
) {
    Column(modifier = modifier) {
        var showAnimation by remember{ mutableStateOf(false) }
        Button(onClick = { showAnimation = !showAnimation }) {
            Text(text = "フラグを切り替える")
        }

        //フラグがtrueの時だけ表示したい
        if(showAnimation) {
            Text("Hello",
                Modifier
                    .fillMaxWidth()
                    .height(200.dp))
        }
    }
}

これをそのまま「条件を満たしたときのみアニメーション付きで表示させたい」と思って以下のように実装すると、
まったくアニメーションせず、AnimatedVisibilityを使わなかった場合と同じ動作になってしまいます。

@Composable
fun AnimatedScreen(
    modifier: Modifier = Modifier
) {
    Column(modifier = modifier) {
        var showAnimation by remember{ mutableStateOf(false) }
        Button(onClick = { showAnimation = !showAnimation }) {
            Text(text = "フラグを切り替える")
        }

        //フラグがtrueの時だけアニメーション付きで表示したい
        if(showAnimation) {
            val density = LocalDensity.current
            AnimatedVisibility(
                visible = showAnimation,
                enter = slideInVertically {
                    // Slide in from 40 dp from the top.
                    with(density) { -40.dp.roundToPx() }
                },
            ) {
                Text("Hello",
                    Modifier
                        .fillMaxWidth()
                        .height(200.dp))
            }
        }
    }
}

device-2023-08-05-125827.gif

解決策

AnimatedVisibilityを使う場合は以下のようにします。

@Composable
fun AnimatedScreen(
    modifier: Modifier = Modifier
) {
    Column(modifier = modifier) {
        var showAnimation by remember{ mutableStateOf(false) }
        Button(onClick = { showAnimation = !showAnimation }) {
            Text(text = "フラグを切り替える")
        }

        //if文は不要!
        val density = LocalDensity.current
        AnimatedVisibility(
            visible = showAnimation,
            enter = slideInVertically {
                // Slide in from 40 dp from the top.
                with(density) { -40.dp.roundToPx() }
            },
        ) {
            Text("Hello",
                Modifier
                    .fillMaxWidth()
                    .height(200.dp))
        }
    }
}

AnimatedVisibilityの中でBooleanを参照しているので、if文で囲む必要はありません。
device-2023-08-05-130328.gif

さいごに

AnimatedVisibilityに渡すBooleanの意味を考えればうまく動かないのは当たり前なのですが、手癖でよく考えずに実装するとやはりダメですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0