Как анимировать появление и исчезновение составной функции в Android?

я делаю обычай Radio Buttonкоторый оборачивает анимацию, когда я перехожу от выбранного к невыбранному и/или наоборот. я использую 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
    ) {

    }
}

1 ответ

AnimatedVisibilityработает, когда visibleотличается между предыдущей и текущей рекомпозицией. В вашем коде всегда true, поэтому анимации не должно быть.

В твоем случае AnimatedContentможет быть использован. Обратите внимание, что использование параметра лямбда имеет решающее значение для функций анимации, таких как эта.

      AnimatedContent(targetState = isSelected) { targetIsSelected ->
    if (targetIsSelected)
        CircleOptionSelected(modifier = modifier)
    else
        CircleOptionUnselected(modifier = modifier)
}
Другие вопросы по тегам