0Pricing
Android Academy · Урок

AnimatedVisibility и переходы

Анимируйте появление и скрытие содержимого

«AnimatedVisibility и переходы» — бесплатный урок Android Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 4 уроков всего.

Анимация появления

Резкое появление и скрытие содержимого выглядит неприятно. AnimatedVisibility в Compose анимирует компонуемый элемент при его появлении в разметке и удалении из неё.

Оберните в него содержимое и управляйте видимостью с помощью логического значения. При изменении этого значения Compose воспроизводит анимацию появления или исчезновения вместо мгновенного появления или удаления.

@Composable
fun Greeting(show: Boolean) {
    AnimatedVisibility(visible = show) {
        Text("Welcome aboard!")
    }
}

Переходы появления и исчезновения

Вы можете точно выбрать, как содержимое появляется и исчезает, с помощью параметров enter и exit. Распространённые строительные блоки включают fadeIn/fadeOut, slideIn/slideOut и expandVertically/shrinkVertically.

Объединяйте их оператором +, чтобы запускать несколько анимаций одновременно.

@Composable
fun Toast(show: Boolean) {
    AnimatedVisibility(
        visible = show,
        enter = fadeIn() + slideInVertically { it },
        exit = fadeOut() + slideOutVertically { it }
    ) {
        Text("Item added to cart")
    }
}

Настройка спецификации перехода

Каждый переход появления или исчезновения принимает animationSpec, поэтому Вы можете управлять длительностью и кривой плавности так же, как с помощью animate*AsState.

Здесь содержимое появляется за 300 мс, а исчезает быстрее — за 150 мс. Это распространённый приём, благодаря которому закрытие выглядит быстрым.

AnimatedVisibility(
    visible = show,
    enter = fadeIn(animationSpec = tween(300)),
    exit = fadeOut(animationSpec = tween(150))
) {
    Card { Text("Details") }
}

Разворачивание и сворачивание

Для разделов, в которых раскрывается дополнительное содержимое, expandVertically и shrinkVertically анимируют высоту, плавно сдвигая окружающее содержимое.

Это идеально подходит для сворачиваемых панелей, элементов раздела FAQ или разделов «показать больше».

@Composable
fun Details(expanded: Boolean) {
    AnimatedVisibility(
        visible = expanded,
        enter = expandVertically() + fadeIn(),
        exit = shrinkVertically() + fadeOut()
    ) {
        Text("Extra details revealed when expanded.")
    }
}

updateTransition: одно состояние, много значений

Когда несколько свойств должны изменяться вместе в зависимости от одного состояния, updateTransition координирует их. Он создаёт объект Transition, дочерние элементы которого анимируются синхронно.

Определите состояние, а затем используйте animateColor, animateDp и другие функции для каждого свойства как функции этого состояния.

enum class BoxState { Collapsed, Expanded }

@Composable
fun MorphingBox(state: BoxState) {
    val transition = updateTransition(state, label = "box")
    val size by transition.animateDp(label = "size") {
        if (it == BoxState.Expanded) 200.dp else 100.dp
    }
    val color by transition.animateColor(label = "color") {
        if (it == BoxState.Expanded) Color.Magenta else Color.Cyan
    }
    Box(Modifier.size(size).background(color))
}

Индивидуальное время для свойств перехода

Важное преимущество updateTransition — возможность задавать время отдельно для каждого свойства. Каждый дочерний элемент animate* может предоставить собственный transitionSpec, поэтому цвет и размер могут изменяться с разной скоростью, оставаясь согласованными одним состоянием.

val size by transition.animateDp(
    transitionSpec = { tween(durationMillis = 300) },
    label = "size"
) { if (it == BoxState.Expanded) 200.dp else 100.dp }

val corner by transition.animateDp(
    transitionSpec = { tween(durationMillis = 600) },
    label = "corner"
) { if (it == BoxState.Expanded) 0.dp else 24.dp }

AnimatedContent: замена содержимого

Когда изменяется само содержимое, а не только его видимость, используйте AnimatedContent. Он анимирует переход от старого содержимого к новому, по умолчанию выполняя плавное смешивание.

Это идеально подходит для счётчика, индикатора шага или переключения между состояниями загрузки и готового содержимого.

@Composable
fun Counter(count: Int) {
    AnimatedContent(
        targetState = count,
        label = "counter"
    ) { value ->
        Text("$value", style = MaterialTheme.typography.headlineLarge)
    }
}

Настройка переходов AnimatedContent

Настройте способ замены содержимого в AnimatedContent с помощью transitionSpec. Классический вариант для счётчика — сдвигать новое значение вверх, пока старое уходит, и одновременно применять затухание.

Ключевое слово using присоединяет SizeTransform, поэтому контейнер также плавно изменяет размер.

AnimatedContent(
    targetState = count,
    transitionSpec = {
        (slideInVertically { it } + fadeIn()) togetherWith
            (slideOutVertically { -it } + fadeOut())
    },
    label = "counter"
) { value -> Text("$value") }

Анимация элементов списка

Внутри LazyColumn добавленные, удалённые или перемещённые элементы могут плавно занимать новое положение с помощью Modifier.animateItem(), применённого к содержимому каждого элемента.

Это обеспечивает плавную сортировку и вставку без ручного отслеживания изменений.

LazyColumn {
    items(tasks, key = { it.id }) { task ->
        Text(
            task.title,
            modifier = Modifier.animateItem()
        )
    }
}

Плавный переход между целыми экранами

Crossfade — простой специализированный вспомогательный инструмент, который выполняет плавный переход между двумя состояниями. Он отлично подходит для переключения целых экранов или крупных состояний интерфейса.

Передайте текущее состояние и лямбду содержимого; при изменении состояния Crossfade плавно скрывает старое содержимое и показывает новое.

@Composable
fun ScreenHost(screen: Screen) {
    Crossfade(targetState = screen, label = "screen") { current ->
        when (current) {
            Screen.Home -> HomeScreen()
            Screen.Profile -> ProfileScreen()
        }
    }
}

Координация появления дочерних элементов

Внутри блока AnimatedVisibility Вы получаете AnimatedVisibilityScope, который предоставляет Modifier.animateEnterExit(). Это позволяет отдельным дочерним элементам анимироваться при появлении и исчезновении поверх перехода родительского элемента.

Например, панель может выезжать, а её заголовок — появляться с небольшим запозданием, создавая многоуровневый эффект.

AnimatedVisibility(visible = show, enter = slideInVertically()) {
    Column {
        Text(
            "Title",
            modifier = Modifier.animateEnterExit(
                enter = fadeIn(tween(delayMillis = 100))
            )
        )
        Text("Body")
    }
}

Быстрая проверка

Вы хотите анимировать замену числа 3 на число 4, плавно показывая новое значение со сдвигом. Какой API лучше всего подходит?

Итоги: видимость и переходы

Теперь Вы умеете анимировать появление, исчезновение и изменение содержимого:

  • AnimatedVisibility анимирует появление и исчезновение с помощью fadeIn/Out, slideIn/Out, expand/shrink, которые можно объединять оператором +.
  • updateTransition координирует множество значений из одного состояния, причём для каждого можно задать собственную спецификацию.
  • AnimatedContent анимирует замену одного содержимого другим; Crossfade — простой вариант с плавным смешиванием.
  • Modifier.animateItem() анимирует вставку и сортировку элементов списка.

Далее: жесты и основанные на физике пружинные анимации для естественного интерактивного движения.

Часто задаваемые вопросы

Урок «AnimatedVisibility и переходы» бесплатный?

Да — полный текст урока «AnimatedVisibility и переходы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 4 уроков всего.

Чему я научусь в уроке «AnimatedVisibility и переходы»?

Анимируйте появление и скрытие содержимого Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «AnimatedVisibility и переходы»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужны анимации
  2. Основы animate*AsState
  3. AnimatedVisibility и переходы
  4. Анимации жестов и пружин
← Назад к Android Academy