Animate visibility in compose

Spr*_*eek 9 android android-jetpack-compose jetpack-compose-animation compose-recomposition

I have a text which need to be animated to show and hide with the value is null or not. it would have been straight forward if the visibility is separately handle, but this is what I got. In the bellow code the enter animation works but the exit animation dont as the text value is null. I can think of something with remembering the old value but not sure how.

@Composable
fun ShowAnimatedText(
    text : String?
) {
    Column(
        modifier = Modifier.fillMaxWidth()
    ) {
        AnimatedVisibility(
            visible = text != null,
            enter = fadeIn(animationSpec = tween(2000)),
            exit = fadeOut(animationSpec = tween(2000))
        ) {
            text?.let {
                Text(text = it)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

z.g*_*g.y 5

我认为淡出动画实际上是“本身”起作用的。

我怀疑该参数text: String?是来自上方某处的提升“状态”的值ShowAnimatedText,并且由于您直接在动画范围内观察它因此当您将其更改为 null 时,它会立即删除Text可组合项,并且您不会看到缓慢淡出。

AnimatedVisibility(
    ...
) {
    text?.let { // your'e directly observing a state over here
        Text(text = it)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试根据我的假设完成您的片段并使其发挥作用,淡入有效,但所需的淡出会立即发生。

@Composable
fun SomeScreen() {

    var text by remember {
        mutableStateOf<String?>("Initial Value")
    }

    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Button(onClick = {
            text = "New Value"
        }) {
            Text("Set New Value")
        }

        Button(onClick = {
            text = null
        }) {
            Text("Remove Value")
        }

        AnimatedText(text = text)
    }
}

@Composable
fun ShowAnimatedText(
    text : String?
) {
    Column(
        modifier = Modifier.fillMaxWidth()
    ) {
        AnimatedVisibility(
            visible = text != null,
            enter = fadeIn(animationSpec = tween(2000)),
            exit = fadeOut(animationSpec = tween(2000))
        ) {
            text?.let {
                Text(text = it)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以通过将 修改text为非状态值来解决此问题,并将可见性逻辑从使用可空性检查更改为某些“业务逻辑”,这需要它是visiblehidden,像这样修改上面的代码。

@Composable
fun SomeScreen() {

    var show by remember {
        mutableStateOf(true)
    }

    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Button(onClick = {
            show = !show
        }) {
            Text("Set New Value")
        }

        AnimatedText(text = "Just A Value", show)
    }
}

@Composable
fun ShowAnimatedText(
    text : String?,
    show: Boolean
) {

    Column(
        modifier = Modifier.fillMaxWidth()
    ) {
        AnimatedVisibility(
            visible = show,
            enter = fadeIn(animationSpec = tween(2000)),
            exit = fadeOut(animationSpec = tween(2000))
        ) {

            text?.let {
                Text(text = it)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述