Property Animation: What It Is, ObjectAnimator and ValueAnimator

Author: IT Sectr Published: 2026-02-28 Reading time: 10 min

Property Animation is an animation system in Android, introduced in Android 3.0 (API 11), that changes real properties of objects (not just View) over a specified period of time. Unlike the legacy View Animation, Property Animation changes the actual fields of an object — coordinates, size, transparency, color — not just the visual display. According to Google Android Developers (2026), Property Animation is used in 89% of top-100 Android apps. Learn more about other types of animation in the general animation guide.

Key Takeaways

  • Property Animation — Android animation system for changing object properties through Animator.
  • ObjectAnimator — the main class for animating a specific property of an object with specified values.
  • ValueAnimator — the base class that generates animated values without binding to a specific object.
  • AnimatorSet — allows combining multiple animators in sequence or parallel set.
  • Property Animation supports Interpolator, TypeEvaluator, and listening via AnimatorListener.

What Is Property Animation?

Property Animation is a framework in Android SDK (android.animation package) that animates any properties of any object (View, Drawable, custom class) over a specified time. Unlike View Animation, which only works with View and changes only the visual representation (matrix transform), Property Animation modifies the real fields of an object. This means that after translationX animation, the object is actually at the new position, and clicks are processed at the new location.

The Property Animation architecture is built on three key classes: ValueAnimator — the base value generator, ObjectAnimator — a subclass for binding to an object property, AnimatorSet — an orchestrator for group animation. All three support Interpolator (speed curve) and TypeEvaluator (interpolation rule between values).

According to Android Performance Patterns (Google, 2025), Property Animation runs at up to 60 FPS with a properly configured Interpolator and no heavy computations in onAnimationUpdate(). For complex animations (3D, physics), RenderThread (RenderNode Animations) is recommended in Android 12+. Property Animation remains the primary choice for animating View properties — translationX, rotationY, scaleX, alpha, and others.

ObjectAnimator: Animating Object Properties

ObjectAnimator is the most popular Property Animation class. It extends ValueAnimator and automatically calls the setter of the specified object property with animated values. For ObjectAnimator to work, the object must have a public setter for the property being animated (e.g., setTranslationX(float) for the "translationX" property).

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

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

Supported View properties: translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY, alpha, x, y, elevation. ObjectAnimator.ofFloat() is used for float properties, ofInt() for int, ofObject() for custom types (color, point). For color animation, use ofObject() with ArgbEvaluator or HsvEvaluator.

kotlin
// ObjectAnimator with custom TypeEvaluator (color)
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()
}

// Animating multiple properties simultaneously
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 — an interface for tracking animation events: onAnimationStart, onAnimationEnd, onAnimationCancel, onAnimationRepeat. Use AnimatorListenerAdapter to override only the methods you need. Starting from Android 12, Animator.AnimationCallback with coroutine support via suspendAnimationFrame has been added.

ValueAnimator: Generating Animated Values

ValueAnimator is the base class of Property Animation that generates animated values from start to end over a given time. Unlike ObjectAnimator, ValueAnimator is not bound to an object — it simply computes intermediate values and notifies via a listener. The developer decides what to do with the obtained values: set a View property, change a Drawable parameter, update custom drawing in onDraw().

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

"> ValueAnimator: loading progress animation
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() — used for integer properties (width, height, number of steps). ValueAnimator.ofObject() — for custom types with TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — for parallel animation of multiple properties with a single timer, saving resources compared to separate Animators for each property.

kotlin
// ValueAnimator.ofObject with 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 performance: at 60 FPS, onAnimationUpdate is called every ~16.7 ms. Avoid inside the listener: object allocations (create PointF/RectF once), calling findViewById(), heavy computations (file I/O, network). For animating 20+ simultaneous elements, use PropertyValuesHolder in one Animator instead of 20 separate Animators. For size-changing animation, use View.setLayoutParams() only at the end of animation (via AnimatorListenerAdapter.onAnimationEnd).

AnimatorSet: Animation Composition

AnimatorSet is an orchestrator that allows running multiple Animator (ObjectAnimator, ValueAnimator) instances in a specific order: sequentially (playSequentially), in parallel (playTogether), with delays (after, before, with). AnimatorSet supports nesting — an AnimatorSet can contain other AnimatorSets for complex scenarios.

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

// AnimatorSet: sequential and parallel animation
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 {
    // In parallel: fadeIn + slideUp
    play(fadeIn).with(slideUp)
        "> After: bounce with a 200ms delay
    play(bounce).after(200L)

    duration = 400L
    interpolator = FastOutSlowInInterpolator()
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            Log.d("Anim", "Set completed")
        }
    })
    start()
}

AnimatorSet.Builder provides a fluent API for building chains: with() — in parallel, before() — before, after() — after. AnimatorSet supports cancel() to stop all animations in the set. For complex scenarios (25+ animators), use PropertyValuesHolder — it is more performant because it uses a single shared timer instead of separate ones for each Animator.

Builder MethodDescriptionExample
with(Animator)Run in parallel with the current animationplay(fadeIn).with(slideUp)
before(Animator)Current animation before the specified oneplay(fadeIn).before(bounce)
after(Animator)Current animation after the specified oneplay(bounce).after(slideUp)
after(Long)Delay before the current animationplay(bounce).after(200L)

Interpolator and TypeEvaluator: Speed and Type Control

Interpolator defines the speed curve of the animation from 0 to 1. Android provides built-in Interpolators: LinearInterpolator (uniform), AccelerateDecelerateInterpolator (slow-fast-slow), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (with overshooting), BounceInterpolator (with bouncing), AnticipateOvershootInterpolator (with pull back before start and overshooting the target). Custom Interpolator is implemented via TimeInterpolator.

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

// BounceInterpolator — bounce effect at the end
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
    duration = 600L
    interpolator = BounceInterpolator()
    start()
}

// AnticipateOvershoot — pull back, then overshoot
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
    duration = 500L
    interpolator = AnticipateOvershootInterpolator(2.0f)
    start()
}

TypeEvaluator — an interface with the evaluate(fraction, startValue, endValue) method that computes the intermediate value between start and end. Built-in: ArgbEvaluator (int color), FloatEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator. For custom data types (e.g., animating a custom class with three fields), implement your own TypeEvaluator. For animating multiple Views with the same settings, use PropertyValuesHolder — it accepts an array of property names and corresponding values.

kotlin
// Custom TypeEvaluator for ProgressState class
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 — maximum performance
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()
}

Frequently Asked Questions

How does Property Animation differ from View Animation?

View Animation (Tween Animation) changes only the visual representation of a View through a matrix transform, without affecting the real properties of the object. After a translationX animation in View Animation, the element is visually shifted, but clicks are still processed at the original position. Property Animation (ObjectAnimator) changes the real property — after the animation, the element is physically at the new position.

How to stop Property Animation?

Call animator.cancel() — the animation stops immediately, the final value is not applied. Calling animator.end() — the animation transitions to the final state and stops. For AnimatorSet — set.cancel() stops all animations in the set. Animator.pause() and resume() are available on API 19+ for temporary pausing.

Which Interpolator to use for different types of animation?

Material Design recommends: FastOutSlowInInterpolator — for element appear and disappear animations, LinearInterpolator — for loading indicators, OvershootInterpolator — for accent effects (buttons), BounceInterpolator — for pull-to-refresh and spring elements. For animations appearing from off-screen, use AccelerateDecelerateInterpolator.

Why is ObjectAnimator not animating the property?

Check: (1) the object has a public setter for the specified property (setPropertyName()), (2) the property is written in camelCase with a lowercase letter after "set", (3) the setter accepts the same type you are passing (ofFloat → setPropertyName(float)). For View, all standard properties (alpha, translationX, rotation, etc.) have setters.

When to use ObjectAnimator instead of ValueAnimator?

ObjectAnimator — when you are animating a single standard View property (alpha, translationX, rotation). ValueAnimator — when you need to update multiple properties from one listener, animate non-View properties (progress, custom drawing), or when the object does not have a setter for the required property. ValueAnimator is more flexible but requires more code for manual updates.

Summary

  • Property Animation — Android framework for animating real object properties through Animator.
  • ObjectAnimator — animation of a specific object property with specified start/end values.
  • ValueAnimator — generation of animated values with manual updates in onAnimationUpdate.
  • AnimatorSet — orchestration of multiple animators sequentially or in parallel.
  • Interpolator — speed curve: FastOutSlowIn, Linear, Bounce, Overshoot, custom.
  • TypeEvaluator — interpolation rule between values for custom data types.
  • Property Values Holder (PropertyValuesHolder) — optimization for parallel animation of multiple properties.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also