I'm making a custom Radio Button that wraps an animation when I go from selected to deselected and/or vice versa. I am using the AnimatedVisibility function of jetpack compose, however I am not getting the expected result.
Notice that in the gif above, despite the buttons changing state normally (selected to deselected and vice versa) the animation is not happening:
At the moment this code does not animate the buttons despite calling the animation function.
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
) {
}
}
CodePudding user response:
AnimatedVisibility works when visible is different between previous and current recompositions. In your code it's always true, so no animation should happen.
In your case AnimatedContent can be used. Note that using lambda parameter is critical with animation functions, like this one.
AnimatedContent(targetState = isSelected) { targetIsSelected ->
if (targetIsSelected)
CircleOptionSelected(modifier = modifier)
else
CircleOptionUnselected(modifier = modifier)
}
