Property Animation: co to jest, ObjectAnimator i ValueAnimator

Autor: IT Sectr Opublikowano: 2026-02-28 Czas czytania: 10 min

Property Animation — system animacji w Android, wprowadzony w Android 3.0 (API 11), który zmienia rzeczywiste właściwości obiektów (nie tylko View) w zadanym przedziale czasu. W przeciwieństwie do przestarzałej View Animation, Property Animation zmienia faktyczne pola obiektu — współrzędne, rozmiar, przezroczystość, kolor — a nie tylko wizualne odtworzenie. Według danych Google Android Developers (2026), Property Animation jest używane w 89% aplikacji Android z top-100. Więcej o innych rodzajach animacji przeczytasz w ogólnym przewodniku po animacji.

Najważniejsze

  • Property Animation — system animacji Android do zmiany właściwości obiektów przez Animator.
  • ObjectAnimator — główna klasa do animacji konkretnej właściwości obiektu z podanymi wartościami.
  • ValueAnimator — klasa bazowa, generująca animowane wartości bez przypisania do konkretnego obiektu.
  • AnimatorSet — pozwala łączyć wiele animatorów w sekwencję lub zestaw równoległy.
  • Property Animation obsługuje Interpolator, TypeEvaluator i nasłuchiwanie przez AnimatorListener.

Co to jest Property Animation?

Property Animation — to framework w Android SDK (pakiet android.animation), który animuje dowolne właściwości dowolnego obiektu (View, Drawable, klasa niestandardowa) w określonym czasie. W przeciwieństwie do View Animation, która działa tylko z View i zmienia jedynie wizualne odtworzenie (matrix transform), Property Animation zmienia rzeczywiste pola obiektu. Oznacza to, że po animacji translationX obiekt rzeczywiście znajduje się w nowej pozycji, a kliknięcia są obsługiwane w nowym miejscu.

Architektura Property Animation opiera się na trzech kluczowych klasach: ValueAnimator — bazowy generator wartości, ObjectAnimator — podklasa do przypisania do właściwości obiektu, AnimatorSet — orkiestrator do animacji grupowej. Wszystkie trzy obsługują Interpolator (krzywa prędkości) i TypeEvaluator (reguła interpolacji między wartościami).

Według danych Android Performance Patterns (Google, 2025), Property Animation działa z częstotliwością do 60 FPS przy prawidłowo skonfigurowanym Interpolator i braku ciężkich obliczeń w onAnimationUpdate(). Dla złożonych animacji (3D, fizyka) zaleca się RenderThread (RenderNode Animations) w Android 12+. Property Animation pozostaje głównym wyborem do animacji właściwości View — translationX, rotationY, scaleX, alpha i innych.

ObjectAnimator: animacja właściwości obiektu

ObjectAnimator — najpopularniejsza klasa Property Animation. Dziedziczy po ValueAnimator i automatycznie wywołuje setter określonej właściwości obiektu z animowanymi wartościami. Do działania ObjectAnimator wymaga, aby obiekt miał publiczny setter dla animowanej właściwości (np. setTranslationX(float) dla właściwości «translationX»).

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

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

Obsługiwane właściwości View: translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY, alpha, x, y, elevation. ObjectAnimator.ofFloat() jest używany dla właściwości float, ofInt() — dla int, ofObject() — dla typów niestandardowych (kolor, punkt). Do animacji koloru użyj ofObject() z ArgbEvaluator lub HsvEvaluator.

kotlin
// ObjectAnimator z niestandardowym TypeEvaluator (kolor)
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()
}

// Animacja wielu właściwości jednocześnie
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 — interfejs do śledzenia zdarzeń animacji: onAnimationStart, onAnimationEnd, onAnimationCancel, onAnimationRepeat. Użyj AnimatorListenerAdapter do nadpisania tylko potrzebnych metod. Od Android 12 dodano Animator.AnimationCallback z obsługą korutyn przez suspendAnimationFrame.

ValueAnimator: generowanie animowanych wartości

ValueAnimator — klasa bazowa Property Animation, która generuje animowane wartości od start do end w zadanym czasie. W przeciwieństwie do ObjectAnimator, ValueAnimator nie jest przypisany do obiektu — po prostu oblicza wartości pośrednie i powiadamia o tym przez słuchacza. Deweloper sam decyduje, co zrobić z otrzymanymi wartościami: ustawić właściwość View, zmienić parametr Drawable, zaktualizować niestandardowe rysowanie w onDraw().

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

"> ValueAnimator: animacja postępu ładowania
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() — używany dla właściwości całkowitoliczbowych (szerokość, wysokość, liczba kroków). ValueAnimator.ofObject() — dla typów niestandardowych z TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — do równoległej animacji wielu właściwości z jednym timerem, co oszczędza zasoby w porównaniu z oddzielnymi Animator dla każdej właściwości.

kotlin
// ValueAnimator.ofObject z 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()
}

Wydajność ValueAnimator: przy częstotliwości 60 FPS onAnimationUpdate jest wywoływane co ~16.7 ms. Unikaj wewnątrz słuchacza: alokacji obiektów (twórz PointF/RectF raz), wywoływania findViewById(), ciężkich obliczeń (wejście-wyjście plików, sieć). Do animacji 20+ jednoczesnych elementów użyj PropertyValuesHolder w jednym Animator zamiast 20 oddzielnych Animator. Do animacji ze zmianą rozmiaru używaj View.setLayoutParams() tylko na końcu animacji (przez AnimatorListenerAdapter.onAnimationEnd).

AnimatorSet: kompozycja animacji

AnimatorSet — orkiestrator, który pozwala uruchamiać wiele Animator (ObjectAnimator, ValueAnimator) w określonej kolejności: sekwencyjnie (playSequentially), równolegle (playTogether), z opóźnieniami (after, before, with). AnimatorSet obsługuje zagnieżdżanie — AnimatorSet może zawierać inne AnimatorSet dla złożonych scenariuszy.

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

// AnimatorSet: animacja sekwencyjna i równoległa
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 {
    // Równolegle: fadeIn + slideUp
    play(fadeIn).with(slideUp)
    "> Po: bounce z opóźnieniem 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 udostępnia fluent API do budowania łańcuchów: with() — równolegle, before() — przed, after() — po. AnimatorSet obsługuje cancel() do zatrzymania wszystkich animacji w secie. Dla złożonych scenariuszy (25+ animatorów) używaj PropertyValuesHolder — jest wydajniejszy, ponieważ używa jednego wspólnego timera zamiast oddzielnych dla każdego Animator.

Metoda BuilderOpisPrzykład
with(Animator)Uruchomienie równolegle z bieżącą animacjąplay(fadeIn).with(slideUp)
before(Animator)Bieżąca animacja przed podanąplay(fadeIn).before(bounce)
after(Animator)Bieżąca animacja po podanejplay(bounce).after(slideUp)
after(Long)Opóźnienie przed bieżącą animacjąplay(bounce).after(200L)

Interpolator i TypeEvaluator: zarządzanie prędkością i typem

Interpolator określa krzywą zmiany prędkości animacji od 0 do 1. Android udostępnia wbudowane Interpolator: LinearInterpolator (równomiernie), AccelerateDecelerateInterpolator (wolno-szybko-wolno), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (z przelotem celu), BounceInterpolator (z odbiciem), AnticipateOvershootInterpolator (z wycofaniem wstecz przed rozpoczęciem i przelotem celu). Niestandardowy Interpolator implementuje się przez TimeInterpolator.

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

// BounceInterpolator — efekt odbicia na końcu
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
    duration = 600L
    interpolator = BounceInterpolator()
    start()
}

// AnticipateOvershoot — wycofanie wstecz, następnie przelot
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
    duration = 500L
    interpolator = AnticipateOvershootInterpolator(2.0f)
    start()
}

TypeEvaluator — interfejs z metodą evaluate(fraction, startValue, endValue), który oblicza wartość pośrednią między start i end. Wbudowane: ArgbEvaluator (kolor int), FloatEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator. Dla niestandardowych typów danych (np. animacja niestandardowej klasy z trzema polami) zaimplementuj własny TypeEvaluator. Do animacji wielu View z tymi samymi ustawieniami używaj PropertyValuesHolder — przyjmuje tablicę nazw właściwości i odpowiadających im wartości.

kotlin
// Niestandardowy TypeEvaluator dla klasy 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 — maksymalna wydajność
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()
}

Często zadawane pytania

Czym różni się Property Animation od View Animation?

View Animation (Tween Animation) zmienia tylko wizualne odtworzenie View przez matrix transform, nie wpływając na rzeczywiste właściwości obiektu. Po animacji translationX w View Animation element jest wizualnie przesunięty, ale kliknięcia są obsługiwane w oryginalnej pozycji. Property Animation (ObjectAnimator) zmienia rzeczywistą właściwość — po animacji element fizycznie znajduje się w nowej pozycji.

Jak zatrzymać Property Animation?

Wywołaj animator.cancel() — animacja zatrzymuje się natychmiast, wartość końcowa nie jest stosowana. Wywołanie animator.end() — animacja przechodzi w stan końcowy i zatrzymuje się. Dla AnimatorSet — set.cancel() zatrzymuje wszystkie animacje w secie. Animator.pause() i resume() są dostępne na API 19+ do tymczasowego wstrzymania.

Którego Interpolator użyć dla różnych typów animacji?

Material Design zaleca: FastOutSlowInInterpolator — do pojawiania się i znikanie elementów, LinearInterpolator — dla wskaźników ładowania, OvershootInterpolator — dla efektów akcentujących (przyciski), BounceInterpolator — dla pull-to-refresh i sprężystych elementów. Do animacji pojawiania się zza krawędzi ekranu używaj AccelerateDecelerateInterpolator.

Dlaczego ObjectAnimator nie animuje właściwości?

Sprawdź: (1) obiekt ma publiczny setter dla podanej właściwości (setPropertyName()), (2) właściwość jest napisana w camelCase z małej litery po «set», (3) setter przyjmuje ten sam typ, który przekazujesz (ofFloat → setPropertyName(float)). Dla View wszystkie standardowe właściwości (alpha, translationX, rotation itd.) mają setter.

Kiedy używać ObjectAnimator zamiast ValueAnimator?

ObjectAnimator — gdy animujesz jedną standardową właściwość View (alpha, translationX, rotation). ValueAnimator — gdy trzeba aktualizować wiele właściwości z jednego słuchacza, animować nie-View właściwości (postęp, niestandardowe rysowanie), lub gdy obiekt nie ma settera dla potrzebnej właściwości. ValueAnimator jest bardziej elastyczny, ale wymaga więcej kodu do ręcznej aktualizacji.

Podsumowanie

  • Property Animation — framework Android do animacji rzeczywistych właściwości obiektów przez Animator.
  • ObjectAnimator — animacja konkretnej właściwości obiektu z zadanymi wartościami start/end.
  • ValueAnimator — generowanie animowanych wartości z ręczną aktualizacją w onAnimationUpdate.
  • AnimatorSet — orkiestracja wielu animatorów sekwencyjnie lub równolegle.
  • Interpolator — krzywa prędkości: FastOutSlowIn, Linear, Bounce, Overshoot, niestandardowe.
  • TypeEvaluator — reguła interpolacji między wartościami dla niestandardowych typów danych.
  • Property Values Holder (PropertyValuesHolder) — optymalizacja dla równoległej animacji wielu właściwości.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również