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 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 — най-популярният клас в Property Animation. Той наследява от ValueAnimator и автоматично извиква setter на посоченото свойство на обекта с анимирани стойности. За работата на ObjectAnimator се изисква обектът да има публичен setter за анимираното свойство (например setTranslationX(float) за свойството «translationX»).
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.
// 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 — базовият клас на Property Animation, който генерира анимирани стойности от start до end за определено време. За разлика от ObjectAnimator, ValueAnimator не е обвързан с обект — той просто изчислява междинните стойности и уведомява чрез слушател. Разработчикът сам решава какво да прави с получените стойности: да зададе свойство на View, да промени параметър на Drawable, да актуализира персонализирано рисуване в onDraw().
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 за всяко свойство.
// 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 — оркестратор, който позволява стартиране на няколко Animator (ObjectAnimator, ValueAnimator) в определен ред: последователно (playSequentially), паралелно (playTogether), със закъснения (after, before, with). AnimatorSet поддържа влагане — AnimatorSet може да съдържа други AnimatorSet за сложни сценарии.
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 определя кривата на промяна на скоростта на анимацията от 0 до 1. Android предоставя вградени Interpolator: LinearInterpolator (равномерно), AccelerateDecelerateInterpolator (бавно-бързо-бавно), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (с превишаване на целта), BounceInterpolator (с отскачане), AnticipateOvershootInterpolator (с отдръпване назад преди началото и превишаване на целта). Персонализиран Interpolator се имплементира чрез TimeInterpolator.
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 — той приема масив от имена на свойства и съответни стойности.
// Персонализиран 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()
}
Често задавани въпроси
View Animation (Tween Animation) променя само визуалното представяне на View чрез matrix transform, без да засяга реалните свойства на обекта. След анимация на translationX в View Animation, елементът е визуално преместен, но кликванията се обработват на оригиналната позиция. Property Animation (ObjectAnimator) променя реалното свойство — след анимацията елементът физически се намира на новата позиция.
Извикайте animator.cancel() — анимацията спира незабавно, крайната стойност не се прилага. Извикване на animator.end() — анимацията преминава в крайно състояние и спира. За AnimatorSet — set.cancel() спира всички анимации в набора. Animator.pause() и resume() са достъпни на API 19+ за временно спиране.
Material Design препоръчва: FastOutSlowInInterpolator — за появяване и изчезване на елементи, LinearInterpolator — за индикатори за зареждане, OvershootInterpolator — за акцентни ефекти (бутони), BounceInterpolator — за pull-to-refresh и пружиниращи елементи. За анимация на появяване от ръба на екрана използвайте AccelerateDecelerateInterpolator.
Проверете: (1) обектът има публичен setter за посоченото свойство (setPropertyName()), (2) свойството е написано в camelCase с малка буква след «set», (3) setter приема същия тип, който предавате (ofFloat → setPropertyName(float)). За View всички стандартни свойства (alpha, translationX, rotation и т.н.) имат setter.
ObjectAnimator — когато анимирате едно стандартно свойство на View (alpha, translationX, rotation). ValueAnimator — когато трябва да актуализирате няколко свойства от един слушател, да анимирате не-View свойства (прогрес, персонализирано рисуване), или когато обектът няма setter за желаното свойство. ValueAnimator е по-гъвкав, но изисква повече код за ръчно актуализиране.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също