0Pricing
Android Academy · Урок

Зачем нужны анимации

Движение, которое направляет пользователей и радует их

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

Осмысленная анимация

Анимации — это не просто украшение. В отличном приложении Android движение направляет внимание, объясняет изменения и делает интерфейс отзывчивым и живым.

В этом курсе Вы изучите API анимации Jetpack Compose: от однострочных помощников animate*AsState до AnimatedVisibility, переходов и пружин на основе физических моделей.

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

Compose анимирует декларативно

В Compose не нужно вручную запускать и останавливать анимации покадрово. Вместо этого Вы задаёте целевое значение, а Compose плавно движется к нему всякий раз, когда это значение изменяется.

Здесь цвет блока определяется одним логическим состоянием. Нажатие меняет состояние, и цвет автоматически плавно изменяется.

@Composable
fun ColorBox() {
    var selected by remember { mutableStateOf(false) }
    val color by animateColorAsState(
        targetValue = if (selected) Color.Green else Color.Gray,
        label = "box-color"
    )
    Box(
        Modifier
            .size(120.dp)
            .background(color)
            .clickable { selected = !selected }
    )
}

Отклик на действия пользователя

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

Мгновенные резкие изменения выглядят как сбой, а короткий переход длительностью 150–300 мс делает интерфейс более качественным. Здесь кнопка слегка уменьшается при нажатии.

@Composable
fun PressableButton(onClick: () -> Unit) {
    var pressed by remember { mutableStateOf(false) }
    val scale by animateFloatAsState(
        targetValue = if (pressed) 0.92f else 1f,
        label = "press-scale"
    )
    Button(
        onClick = onClick,
        modifier = Modifier.graphicsLayer {
            scaleX = scale; scaleY = scale
        }
    ) { Text("Tap me") }
}

Объяснение изменений состояния

Когда интерфейс изменяется, анимация помогает пользователю понять, что только что произошло. Элемент, который плавно появляется и выезжает, воспринимается как «новый», а исчезающий — как «удалённый».

Без движения содержимое может резко появляться или исчезать, и пользователь не понимает, появилось ли что-то, исчезло или переместилось.

@Composable
fun Banner(visible: Boolean) {
    AnimatedVisibility(
        visible = visible,
        enter = fadeIn() + slideInVertically(),
        exit = fadeOut() + slideOutVertically()
    ) {
        Text("Saved successfully!")
    }
}

Непрерывность и ощущение пространства

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

Compose может автоматически анимировать изменения компоновки с помощью Modifier.animateContentSize(), поэтому блок плавно увеличивается или уменьшается при изменении его содержимого.

@Composable
fun ExpandableCard(expanded: Boolean) {
    Column(
        Modifier
            .fillMaxWidth()
            .animateContentSize()
            .padding(16.dp)
    ) {
        Text("Title", style = MaterialTheme.typography.titleMedium)
        if (expanded) {
            Text("Here is the longer body that appears when expanded.")
        }
    }
}

Важны длительность и темп

Хорошая анимация должна быть быстрой. Большинство переходов интерфейса должны длиться примерно от 150 до 400 мс. При слишком медленной анимации приложение кажется неповоротливым, а при слишком быстрой движение становится незаметным.

Compose позволяет настраивать длительность и темп с помощью tween и кривой easing. Сглаживание делает движение естественным, ускоряя и замедляя его.

val offset by animateDpAsState(
    targetValue = if (open) 0.dp else 200.dp,
    animationSpec = tween(
        durationMillis = 300,
        easing = FastOutSlowInEasing
    ),
    label = "panel-offset"
)

Не переусердствуйте

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

Несколько простых правил:

  • Используйте анимацию для передачи смысла, а не для украшения.
  • Делайте переходы короткими и ненавязчивыми.
  • Не анимируйте одновременно всё содержимое экрана.
  • Никогда не мешайте пользователю выполнять действия во время анимации.

Учитывайте доступность

Некоторые пользователи включают параметр Удалить анимации в системных настройках из-за повышенной чувствительности к движению. Внимательное приложение учитывает это предпочтение.

Можно узнать, установлен ли масштаб анимаций равным нулю, и соответственно уменьшить или отключить необязательные движения.

@Composable
fun rememberReduceMotion(): Boolean {
    val context = LocalContext.current
    val scale = Settings.Global.getFloat(
        context.contentResolver,
        Settings.Global.ANIMATOR_DURATION_SCALE,
        1f
    )
    return scale == 0f
}

Набор инструментов анимации Compose

Compose предлагает многоуровневый набор API для анимации. В этом курсе Вы познакомитесь с ними:

  • animate*AsState — анимация одного значения (цвета, размера, числа с плавающей точкой).
  • AnimatedVisibility — анимация появления и исчезновения.
  • updateTransition — согласованная анимация нескольких значений.
  • AnimatedContent — плавное смешивание разных элементов содержимого.
  • Animatable и spring — низкоуровневое управление на основе физики.

Начинайте с высокоуровневых API и переходите на более низкий уровень только при необходимости более точного контроля.

Анимация следует за состоянием

Ментальная модель, которая помогает понять всё остальное: в Compose анимации отслеживают состояние. Вы изменяете значение, а API анимации плавно приближает интерфейс к новому значению на каждом кадре.

Это означает, что Вам редко приходится описывать временную шкалу. Вы объявляете: «это свойство должно быть равно X», а Compose сам обрабатывает промежуточные кадры.

@Composable
fun FadingText(highlighted: Boolean) {
    val alpha by animateFloatAsState(
        targetValue = if (highlighted) 1f else 0.4f,
        label = "text-alpha"
    )
    Text(
        "Status",
        modifier = Modifier.graphicsLayer { this.alpha = alpha }
    )
}

Краткая разминка на чистом Kotlin

Анимации интерполируют значения. В основе лежит простая математика: дробь t от 0 до 1 смешивает начальное и конечное значения. Эта идея — линейная интерполяция, или lerp, — лежит в основе каждой создаваемой Вами анимации.

Этот небольшой фрагмент на чистом Kotlin показывает принцип, который Compose применяет много раз в секунду.

fun lerp(start: Float, end: Float, t: Float): Float =
    start + (end - start) * t

fun main() {
    for (i in 0..4) {
        val t = i / 4f
        println("t=$t -> ${lerp(0f, 100f, t)}")
    }
}

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

Какова основная ментальная модель анимаций в Jetpack Compose?

Итоги: осмысленное движение

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

  • Движение даёт обратную связь, объясняет изменения и сохраняет непрерывность.
  • Анимации Compose являются декларативными и следуют за состоянием.
  • Переходы должны быть короткими (примерно 150–400 мс) и оправданными; не используйте анимацию чрезмерно.
  • Учитывайте потребности пользователей, которые уменьшают количество движения для повышения доступности.
  • Сначала обращайтесь к высокоуровневым API: animate*AsState, AnimatedVisibility, переходам и пружинам.

Далее: анимация отдельных значений с помощью семейства animate*AsState.

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

Урок «Зачем нужны анимации» бесплатный?

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

Чему я научусь в уроке «Зачем нужны анимации»?

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

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

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

Сколько времени занимает урок «Зачем нужны анимации»?

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

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

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

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

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