如何在 Android 中为可组合函数的出现和消失设置动画?
How to animate the appearance and disappearance of a composable function in Android?
我正在制作一个自定义 Radio Button
,当我从选中变为取消选中时包装动画 and/or 反之亦然。我正在使用 jetpack compose 的 AnimatedVisibility
功能,但是我没有得到预期的结果。
请注意,在上面的 gif 中,尽管按钮正常改变状态(选择到取消选择,反之亦然),但动画没有发生:
目前,尽管调用了动画函数,但此代码并未为按钮设置动画。
AnimatedRadioButton
:
@ExperimentalAnimationApi
@Composable
fun AnimatedRadioButton(
modifier: Modifier = Modifier,
isSelected: Boolean,
) {
if (isSelected)
FadeAnimatedContainer {
CircleOptionSelected(modifier = modifier)
}
else
FadeAnimatedContainer {
CircleOptionUnselected(modifier = modifier)
}
}
@ExperimentalAnimationApi
@Composable
private fun FadeAnimatedContainer(
content: @Composable AnimatedVisibilityScope.() -> Unit,
) = AnimatedVisibility(
visible = true,
enter = fadeIn(),
exit = fadeOut(),
content = content
)
CircleOptionSelected
:
@Composable
fun CircleOptionSelected(
modifier: Modifier = Modifier,
@DimenRes ballSize: Int = R.dimen.ball_size // 24dp
) {
val size = dimensionResource(id = ballSize)
Box(
modifier = modifier
.size(size)
.clip(CircleShape)
.background(color = MyRed),
contentAlignment = Alignment.Center
) {
CircleOptionUnselected(ballSize = size / 2)
}
}
CircleOptionUnselected
:
private val UnselectedBallColor = Color(0xFFF2F2F2)
@Composable
fun CircleOptionUnselected(
modifier: Modifier = Modifier,
ballSize: Dp? = null
) {
val size = ballSize ?: dimensionResource(id = R.dimen.ball_size)
Surface(
modifier = modifier.size(size),
shape = CircleShape,
color = UnselectedBallColor
) {
}
}
AnimatedVisibility
在 visible
与之前和当前的重组不同时有效。在您的代码中,它始终是 true
,因此不应出现动画。
在你的情况下可以使用 AnimatedContent
。请注意,使用 lambda 参数对于动画功能至关重要,例如这个。
AnimatedContent(targetState = isSelected) { targetIsSelected ->
if (targetIsSelected)
CircleOptionSelected(modifier = modifier)
else
CircleOptionUnselected(modifier = modifier)
}
我正在制作一个自定义 Radio Button
,当我从选中变为取消选中时包装动画 and/or 反之亦然。我正在使用 jetpack compose 的 AnimatedVisibility
功能,但是我没有得到预期的结果。
请注意,在上面的 gif 中,尽管按钮正常改变状态(选择到取消选择,反之亦然),但动画没有发生:
目前,尽管调用了动画函数,但此代码并未为按钮设置动画。
AnimatedRadioButton
:
@ExperimentalAnimationApi
@Composable
fun AnimatedRadioButton(
modifier: Modifier = Modifier,
isSelected: Boolean,
) {
if (isSelected)
FadeAnimatedContainer {
CircleOptionSelected(modifier = modifier)
}
else
FadeAnimatedContainer {
CircleOptionUnselected(modifier = modifier)
}
}
@ExperimentalAnimationApi
@Composable
private fun FadeAnimatedContainer(
content: @Composable AnimatedVisibilityScope.() -> Unit,
) = AnimatedVisibility(
visible = true,
enter = fadeIn(),
exit = fadeOut(),
content = content
)
CircleOptionSelected
:
@Composable
fun CircleOptionSelected(
modifier: Modifier = Modifier,
@DimenRes ballSize: Int = R.dimen.ball_size // 24dp
) {
val size = dimensionResource(id = ballSize)
Box(
modifier = modifier
.size(size)
.clip(CircleShape)
.background(color = MyRed),
contentAlignment = Alignment.Center
) {
CircleOptionUnselected(ballSize = size / 2)
}
}
CircleOptionUnselected
:
private val UnselectedBallColor = Color(0xFFF2F2F2)
@Composable
fun CircleOptionUnselected(
modifier: Modifier = Modifier,
ballSize: Dp? = null
) {
val size = ballSize ?: dimensionResource(id = R.dimen.ball_size)
Surface(
modifier = modifier.size(size),
shape = CircleShape,
color = UnselectedBallColor
) {
}
}
AnimatedVisibility
在 visible
与之前和当前的重组不同时有效。在您的代码中,它始终是 true
,因此不应出现动画。
在你的情况下可以使用 AnimatedContent
。请注意,使用 lambda 参数对于动画功能至关重要,例如这个。
AnimatedContent(targetState = isSelected) { targetIsSelected ->
if (targetIsSelected)
CircleOptionSelected(modifier = modifier)
else
CircleOptionUnselected(modifier = modifier)
}