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, який генерує анімовані значення від початку до кінця за заданий час. На відміну від 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 мс. Уникайте всередині слухача: алокації об'єктів (створюйте PointF/RectF один раз), виклику findViewById(), важких обчислень (файловий ввід-вивід, мережа). Для анімації 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 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також