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, який генерує анімовані значення від початку до кінця за заданий час. На відміну від 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 — він приймає масив імен властивостей та відповідних значень.

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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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