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)
}