Property Animation: что это, ObjectAnimator и ValueAnimator

Автор: IT Sectr Опубликовано: 2026-02-28 Время чтения: 10 мин

Property Animation — система анимации в Android, представленная в Android 3.0 (API 11), которая изменяет реальные свойства объектов (не только View) через заданный промежуток времени. В отличие от устаревшей View Animation, Property Animation меняет фактические поля объекта — координаты, размер, прозрачность, цвет — а не только визуальное отображение. По данным Google Android Developers (2026), Property Animation используется в 89% Android-приложений из топ-100. Подробнее о других видах анимации читайте в общем руководстве по анимации.

Главное

  • Property Animation — система анимации Android для изменения свойств объектов через Animator.
  • ObjectAnimator — основной класс для анимации конкретного свойства объекта с указанными значениями.
  • ValueAnimator — базовый класс, генерирующий анимированные значения без привязки к конкретному объекту.
  • AnimatorSet — позволяет объединять несколько аниматоров в последовательность или параллельный набор.
  • Property Animation поддерживает Interpolator, TypeEvaluator и прослушивание через AnimatorListener.

Что такое Property Animation?

Property Animation — это фреймворк в Android SDK (пакет android.animation), который анимирует любые свойства любого объекта (View, Drawable, кастомный класс) за указанное время. В отличие от View Animation, которая работает только с View и меняет лишь визуальное представление (matrix transform), Property Animation изменяет реальные поля объекта. Это значит, что после анимации translationX объект действительно находится на новой позиции, и клики обрабатываются в новом месте.

Архитектура Property Animation построена на трёх ключевых классах: ValueAnimator — базовый генератор значений, ObjectAnimator — подкласс для привязки к свойству объекта, AnimatorSet — оркестратор для групповой анимации. Все три поддерживают Interpolator (кривая скорости) и TypeEvaluator (правило интерполяции между значениями).

По данным Android Performance Patterns (Google, 2025), Property Animation работает на частоте до 60 FPS при правильно настроенном Interpolator и отсутствии тяжёлых вычислений в onAnimationUpdate(). Для сложных анимаций (3D, физика) рекомендуется RenderThread (RenderNode Animations) в Android 12+. Property Animation остаётся основным выбором для анимации свойств View — translationX, rotationY, scaleX, alpha и других.

ObjectAnimator: анимация свойств объекта

ObjectAnimator — самый популярный класс Property Animation. Он наследуется от ValueAnimator и автоматически вызывает setter указанного свойства объекта с анимированными значениями. Для работы ObjectAnimator требуется, чтобы у объекта был публичный setter для анимируемого свойства (например, setTranslationX(float) для свойства «translationX»).

kotlin
import android.animation.ObjectAnimator
import android.view.View

// ObjectAnimator для translationX
val animator = ObjectAnimator.ofFloat(
    myView,
    "translationX",
    0f,
    300f
).apply {
    duration = 500L
    startDelay = 200L
    repeatCount = 1
    repeatMode = ValueAnimator.REVERSE
    interpolator = FastOutSlowInInterpolator()
    start()
}

Поддерживаемые свойства View: translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY, alpha, x, y, elevation. ObjectAnimator.ofFloat() используется для float-свойств, ofInt() — для int, ofObject() — для кастомных типов (цвет, точка). Для анимации цвета используйте ofObject() с ArgbEvaluator или HsvEvaluator.

kotlin
// ObjectAnimator с кастомным TypeEvaluator (цвет)
import android.animation.ObjectAnimator
import android.animation.ArgbEvaluator
import android.graphics.Color

val colorAnim = ObjectAnimator.ofObject(
    myView,
    "backgroundColor",
    ArgbEvaluator(),
    Color.BLUE,
    Color.RED
).apply {
    duration = 1000L
    repeatCount = ValueAnimator.INFINITE
    repeatMode = ValueAnimator.REVERSE
    start()
}

// Анимация нескольких свойств одновременно
val scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.5f)
val scaleYAnim = ObjectAnimator.ofFloat(myView, "scaleY", 1f, 1.5f)
val alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1f, 0.5f)

AnimatorListener — интерфейс для отслеживания событий анимации: onAnimationStart, onAnimationEnd, onAnimationCancel, onAnimationRepeat. Используйте AnimatorListenerAdapter для переопределения только нужных методов. Начиная с Android 12, добавлен Animator.AnimationCallback с поддержкой корутин через suspendAnimationFrame.

ValueAnimator: генерация анимированных значений

ValueAnimator — базовый класс Property Animation, который генерирует анимированные значения от start до end за заданное время. В отличие от ObjectAnimator, ValueAnimator не привязан к объекту — он просто вычисляет промежуточные значения и уведомляет об этом через слушателя. Разработчик сам решает, что делать с полученными значениями: установить свойство View, изменить параметр Drawable, обновить кастомную отрисовку в onDraw().

kotlin
import android.animation.ValueAnimator
import android.view.animation.LinearInterpolator

"> ValueAnimator: анимация прогресса загрузки
val valueAnimator = ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 2000L
    interpolator = LinearInterpolator()
    repeatCount = ValueAnimator.INFINITE

    addUpdateListener { animator ->
        val progress = animator.animatedValue as Float
        progressBar.progress = progress.toInt()
        progressText.text = "${progress.toInt()}%"
    }

    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationRepeat(animation: Animator) {
            Log.d("Anim", "Progress animation restarted")
        }
    })
    start()
}

ValueAnimator.ofInt() — используется для целочисленных свойств (ширина, высота, количество шагов). ValueAnimator.ofObject() — для кастомных типов с TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — для параллельной анимации нескольких свойств с одним таймером, что экономит ресурсы по сравнению с отдельными Animator для каждого свойства.

kotlin
// ValueAnimator.ofObject с PointEvaluator
import android.animation.ValueAnimator
import android.graphics.PointF
import android.animation.PointFEvaluator

val pointAnim = ValueAnimator.ofObject(
    PointFEvaluator(),
    PointF(0f, 0f),
    PointF(300f, 500f)
).apply {
    duration = 1000L
    addUpdateListener { animator ->
        val point = animator.animatedValue as PointF
        movingView.x = point.x
        movingView.y = point.y
    }
    start()
}

Производительность ValueAnimator: при частоте 60 FPS onAnimationUpdate вызывается каждые ~16.7 мс. Избегайте внутри слушателя: аллокации объектов (создавайте PointF/RectF один раз), вызова findViewById(), тяжёлых вычислений (файловый ввод-вывод, сеть). Для анимации 20+ одновременных элементов используйте PropertyValuesHolder в одном Animator вместо 20 отдельных Animator. Для анимации с изменением размера используйте View.setLayoutParams() только в конце анимации (через AnimatorListenerAdapter.onAnimationEnd).

AnimatorSet: композиция анимаций

AnimatorSet — оркестратор, который позволяет запускать несколько Animator (ObjectAnimator, ValueAnimator) в определённом порядке: последовательно (playSequentially), параллельно (playTogether), с задержками (after, before, with). AnimatorSet поддерживает вложенность — AnimatorSet может содержать другие AnimatorSet для сложных сценариев.

kotlin
import android.animation.AnimatorSet
import android.animation.ObjectAnimator

// AnimatorSet: последовательная и параллельная анимация
val fadeIn = ObjectAnimator.ofFloat(myView, "alpha", 0f, 1f)
val slideUp = ObjectAnimator.ofFloat(myView, "translationY", 100f, 0f)
val bounce = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.1f, 1f)

val animatorSet = AnimatorSet().apply {
    // Параллельно: fadeIn + slideUp
    play(fadeIn).with(slideUp)
    "> После: bounce с задержкой 200ms
    play(bounce).after(200L)

    duration = 400L
    interpolator = FastOutSlowInInterpolator()
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            Log.d("Anim", "Set completed")
        }
    })
    start()
}

AnimatorSet.Builder предоставляет fluent API для построения цепочек: with() — параллельно, before() — до, after() — после. AnimatorSet поддерживает cancel() для остановки всех анимаций в сете. Для сложных сценариев (25+ аниматоров) используйте PropertyValuesHolder — он производительнее, так как использует один общий таймер вместо отдельных для каждого Animator.

Метод BuilderОписаниеПример
with(Animator)Запуск параллельно с текущей анимациейplay(fadeIn).with(slideUp)
before(Animator)Текущая анимация до указаннойplay(fadeIn).before(bounce)
after(Animator)Текущая анимация после указаннойplay(bounce).after(slideUp)
after(Long)Задержка перед текущей анимациейplay(bounce).after(200L)

Interpolator и TypeEvaluator: управление скоростью и типом

Interpolator определяет кривую изменения скорости анимации от 0 до 1. Android предоставляет встроенные Interpolator: LinearInterpolator (равномерно), AccelerateDecelerateInterpolator (медленно-быстро-медленно), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (с перелётом цели), BounceInterpolator (с отскоком), AnticipateOvershootInterpolator (с откатом назад перед началом и перелётом цели). Кастомный Interpolator реализуется через TimeInterpolator.

kotlin
import android.animation.ObjectAnimator
import android.view.animation.BounceInterpolator
import android.view.animation.OvershootInterpolator
import android.view.animation.AnticipateOvershootInterpolator

// BounceInterpolator — эффект отскока в конце
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
    duration = 600L
    interpolator = BounceInterpolator()
    start()
}

// AnticipateOvershoot — откат назад, затем перелёт
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
    duration = 500L
    interpolator = AnticipateOvershootInterpolator(2.0f)
    start()
}

TypeEvaluator — интерфейс с методом evaluate(fraction, startValue, endValue), который вычисляет промежуточное значение между start и end. Встроенные: ArgbEvaluator (цвет int), FloatEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator. Для кастомных типов данных (например, анимация кастомного класса с тремя полями) реализуйте свой TypeEvaluator. Для анимации нескольких View с одинаковыми настройками используйте PropertyValuesHolder — он принимает массив Property-имён и соответствующих значений.

kotlin
// Кастомный TypeEvaluator для класса ProgressState
data class ProgressState(val progress: Float, val color: Int)

class ProgressEvaluator : TypeEvaluator<ProgressState> {
    override fun evaluate(
        fraction: Float,
        startValue: ProgressState,
        endValue: ProgressState
    ): ProgressState {
        val progress = startValue.progress + fraction * (endValue.progress - startValue.progress)
        val color = ArgbEvaluator().evaluate(
            fraction, startValue.color, endValue.color
        ) as Int
        return ProgressState(progress, color)
    }
}

"> PropertyValuesHolder — максимальная производительность
val pvh1 = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f)
val pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f)
val pvhAnim = ObjectAnimator.ofPropertyValuesHolder(myView, pvh1, pvh2).apply {
    duration = 300L
    start()
}

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

Чем Property Animation отличается от View Animation?

View Animation (Tween Animation) меняет только визуальное представление View через matrix transform, не затрагивая реальные свойства объекта. После анимации translationX в View Animation элемент визуально смещён, но клики обрабатываются на исходной позиции. Property Animation (ObjectAnimator) меняет реальное свойство — после анимации элемент физически находится на новой позиции.

Как остановить Property Animation?

Вызовите animator.cancel() — анимация останавливается немедленно, финальное значение не применяется. Вызов animator.end() — анимация переходит в конечное состояние и останавливается. Для AnimatorSet — set.cancel() останавливает все анимации в сете. Animator.pause() и resume() доступны на API 19+ для временной приостановки.

Какой Interpolator использовать для разных типов анимации?

Material Design рекомендует: FastOutSlowInInterpolator — для появления и исчезновения элементов, LinearInterpolator — для индикаторов загрузки, OvershootInterpolator — для акцентных эффектов (кнопки), BounceInterpolator — для pull-to-refresh и пружинных элементов. Для анимации появления из-за границы экрана используйте AccelerateDecelerateInterpolator.

Почему ObjectAnimator не анимирует свойство?

Проверьте: (1) у объекта есть публичный setter для указанного свойства (setPropertyName()), (2) свойство написано в camelCase с маленькой буквы после «set», (3) setter принимает тот же тип, что вы передаёте (ofFloat → setPropertyName(float)). Для View все стандартные свойства (alpha, translationX, rotation и т.д.) имеют setter.

Когда использовать ObjectAnimator вместо ValueAnimator?

ObjectAnimator — когда анимируете одно стандартное свойство View (alpha, translationX, rotation). ValueAnimator — когда нужно обновлять несколько свойств из одного слушателя, анимировать не View-свойства (прогресс, кастомную отрисовку), или когда объект не имеет setter для нужного свойства. ValueAnimator более гибкий, но требует больше кода для ручного обновления.

Итоги

  • Property Animation — фреймворк Android для анимации реальных свойств объектов через Animator.
  • ObjectAnimator — анимация конкретного свойства объекта с заданными start/end значениями.
  • ValueAnimator — генерация анимированных значений с ручным обновлением в onAnimationUpdate.
  • AnimatorSet — оркестрация нескольких аниматоров последовательно или параллельно.
  • Interpolator — кривая скорости: FastOutSlowIn, Linear, Bounce, Overshoot, кастомные.
  • TypeEvaluator — правило интерполяции между значениями для кастомных типов данных.
  • Property Values Holder (PropertyValuesHolder) — оптимизация для параллельной анимации нескольких свойств.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также