← Назад к вопросам

Как работает ValueAnimator?

1.8 Middle🔥 122 комментариев
#Android компоненты#UI и вёрстка

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как работает ValueAnimator?

ValueAnimator — это один из фундаментальных классов в системе анимации Android, входящий в пакет android.animation. Он не управляет напрямую свойствами UI-объектов (в отличие от ObjectAnimator), а генерирует последовательность значений за определённый промежуток времени, следуя заданному алгоритму интерполяции. Эти значения затем можно использовать для обновления любых произвольных свойств.

Основной принцип работы

В основе ValueAnimator лежит механизм временной шкалы (timeline). Аниматор вычисляет дробный прогресс (fraction) анимации от 0.0 до 1.0 в зависимости от прошедшего времени, длительности и заданного интерполятора. Затем этот прогресс преобразуется в конкретное значение между начальным (startValue) и конечным (endValue).

val animator = ValueAnimator.ofFloat(0f, 360f).apply {
    duration = 1000 // Длительность 1 секунда
    interpolator = AccelerateDecelerateInterpolator() // Интерполятор
    addUpdateListener { animation ->
        val animatedValue = animation.animatedValue as Float
        // Используем animatedValue, например, для поворота View
        myView.rotation = animatedValue
    }
}
animator.start()

Ключевые компоненты ValueAnimator

  1. Типы значений: ValueAnimator поддерживает примитивные типы через фабричные методы:
    *   `ofInt(int... values)`
    *   `ofFloat(float... values)`
    *   `ofArgb(int... values)` (специально для цветов)
    *   `ofObject(TypeEvaluator, Object... values)` для произвольных объектов.

  1. Интерполятор (Interpolator): Определяет математическую функцию, которая преобразует линейный прогресс времени в нелинейный прогресс анимации. Например:
    *   `LinearInterpolator()` — равномерная анимация.
    *   `AccelerateDecelerateInterpolator()` — ускорение в начале и замедление в конце.
    *   `BounceInterpolator()` — эффект отскока.

  1. Оценщик (TypeEvaluator): Отвечает за расчёт промежуточного значения между двумя ключевыми кадрами на основе текущей доли прогресса. Для стандартных типов (Int, Float, Color) используются встроенные оценщики (IntEvaluator, FloatEvaluator, ArgbEvaluator). Для кастомных объектов необходимо реализовать интерфейс TypeEvaluator<T>.
class PointEvaluator : TypeEvaluator<PointF> {
    override fun evaluate(fraction: Float, startValue: PointF, endValue: PointF): PointF {
        return PointF(
            startValue.x + fraction * (endValue.x - startValue.x),
            startValue.y + fraction * (endValue.y - startValue.y)
        )
    }
}

Внутренняя работа и жизненный цикл

  1. Запуск: Вызов start() регистрирует аниматор в общем таймере анимаций (AnimationHandler), который синхронизирован с частота обновления экрана (vsync, обычно 60 Гц). Это гарантирует, что кадры анимации будут вычисляться в начале каждого цикла отрисовки.

  2. Расчёт кадра: В каждом кадре система:

    *   Определяет текущее время анимации.
    *   Вычисляет дробный прогресс (`fraction`) с учётом интерполятора.
    *   Использует `TypeEvaluator` для расчёта текущего значения между ключевыми точками на основе прогресса.
    *   Вызывает всех зарегистрированных слушателей `AnimatorUpdateListener`.

  1. Этапы жизненного цикла: Аниматор проходит состояния STARTED, RUNNING и при завершении — ENDED. Можно отслеживать их через AnimatorListener.

Отличия от ObjectAnimator

  • ValueAnimatorдвижок вычисления значений. Он только генерирует числа и требует AnimatorUpdateListener для их применения.
  • ObjectAnimator (наследник ValueAnimator) — "автоматизированная" обёртка. Он принимает целевой объект, имя его свойства (через рефлексию или setter) и самостоятельно обновляет это свойство каждому кадру.

Оптимизация и внутреннее устройство

  • Аппаратное ускорение: Сама работа ValueAnimator не использует аппаратное ускорение напрямую, но значения, которые он генерирует, могут применяться к свойствам, поддерживающим рендеринг через проекционные поверхности (RenderThread), например, translationX, translationY, rotation, alpha. Это снижает нагрузку на основной поток.
  • Пул аниматоров (AnimationHandler): Все активные аниматоры управляются единым планировщиком, что минимизирует накладные расходы и обеспечивает синхронизацию.

Практический пример: Анимация кастомного свойства

// Анимация радиуса круга для кастомной View
val radiusAnimator = ValueAnimator.ofInt(initialRadius, expandedRadius).apply {
    duration = 500
    interpolator = OvershootInterpolator()
    addUpdateListener {
        myCustomView.radius = it.animatedValue as Int // Обновляем кастомное свойство
        myCustomView.invalidate() // Запрашиваем перерисовку
    }
}

Итог: ValueAnimator — это гибкий и мощный инструмент для создания временных шкал изменений значений. Он отделяет логику расчёта промежуточных состояний от логики их применения, что позволяет анимировать любые свойства, а не только атрибуты View. Его понимание является ключевым для создания сложных, плавных и производительных анимаций в Android-приложениях.

Как работает ValueAnimator? | PrepBro