Как использовать AnimatedVisibility с нулевыми значениями?

Я довольно часто попадаю в такую ​​ситуацию. У меня есть некоторое значение, как в приведенном ниже примере, и я хочу показать/скрыть его в зависимости от того, является ли оно нулевым или нет. Но скрыть это всегда не удается, поскольку ничего не отображается всякий раз, когда оно равно нулю, и анимация просто привязывается к пустому небытию.

Как я могу заставить это работать? я хотел бы сохранить platesвокруг, пока анимация не закончится.

          AnimatedVisibility(
        visible = plates != null,
        content = {
            if (plates != null) {
                // Render plates
            } else {
                // The animation snaps to nothingness, as opposed to animating out
            }
        })

3 ответа

Это то, что я в итоге сделал, и это работает, как и ожидалось!

      @Composable
inline fun <T> AnimatedValueVisibility(
    value: T?,
    enter: EnterTransition = fadeIn(
        animationSpec = FloatSpec
    ) + expandVertically(
        animationSpec = SizeSpec,
        clip = false
    ),
    exit: ExitTransition = fadeOut(
        animationSpec = FloatSpec
    ) + shrinkVertically(
        animationSpec = SizeSpec,
        clip = false
    ),
    crossinline content: @Composable (T) -> Unit
) {
    val ref = remember {
        Ref<T>()
    }

    ref.value = value ?: ref.value

    AnimatedVisibility(
        visible = value != null,
        enter = enter,
        exit = exit,
        content = {
            ref.value?.let { value ->
                content(value)
            }
        }
    )
}

Возможно, я немного опоздал на вечеринку, но есть ещеAnimatedContentсборный. Для этого по-прежнему требуется согласие наExperimentalAnimationApi, однако он передаст модель обратно через свой составной лямбда-параметр, и вы можете проверить его на обнуляемость. Вот как это будет работать:

      import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable

@Composable
@OptIn(ExperimentalAnimationApi::class)
fun AnimatedPlates(plates: Plates?) {
    AnimatedContent(plates) { plates ->
        if (plates != null) {
            // Render plates
        } else {
            // Render either nothing, or some empty state.
        }
    }
}

Надеюсь, это поможет!

Анимация всегда требует контента, даже когда нечего показывать. Просто отобразите поверхность, когда содержимое равно null (или пусто):

      AnimatedVisibility(
        visible = plates != null,
        content = {
            if (plates != null) {
                // Render plates
            } else {
                Surface(modifier = Modifier.fillMaxSize()) { }
            }
        })
Другие вопросы по тегам