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 ms. Избягвайте в рамките на слушателя: разпределяне на обекти (създавайте PointF/RectF веднъж), извикване на findViewById(), тежки изчисления (файлов I/O, мрежа). За анимация на 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също