Property Animation es un sistema de animación en Android, introducido en Android 3.0 (API 11), que cambia propiedades reales de objetos (no solo View) durante un período de tiempo determinado. A diferencia de la View Animation heredada, Property Animation modifica los campos reales del objeto — coordenadas, tamaño, transparencia, color — y no solo la representación visual. Según Google Android Developers (2026), Property Animation se utiliza en el 89% de las aplicaciones Android del top 100. Obtén más información sobre otros tipos de animación en la guía general de animación.
Puntos clave
Property Animation es un framework en Android SDK (paquete android.animation) que anima cualquier propiedad de cualquier objeto (View, Drawable, clase personalizada) durante un tiempo especificado. A diferencia de View Animation, que solo funciona con View y cambia únicamente la representación visual (matrix transform), Property Animation modifica los campos reales del objeto. Esto significa que después de una animación de translationX, el objeto realmente está en la nueva posición y los clics se procesan en la nueva ubicación.
La arquitectura de Property Animation se basa en tres clases clave: ValueAnimator — el generador base de valores, ObjectAnimator — una subclase para vincularse a una propiedad del objeto, AnimatorSet — un orquestador para animaciones grupales. Las tres admiten Interpolator (curva de velocidad) y TypeEvaluator (regla de interpolación entre valores).
Según Android Performance Patterns (Google, 2025), Property Animation funciona hasta 60 FPS con un Interpolator configurado correctamente y sin cálculos pesados en onAnimationUpdate(). Para animaciones complejas (3D, física), se recomienda RenderThread (RenderNode Animations) en Android 12+. Property Animation sigue siendo la opción principal para animar propiedades de View — translationX, rotationY, scaleX, alpha y otras.
ObjectAnimator es la clase más popular de Property Animation. Extiende ValueAnimator y llama automáticamente al setter de la propiedad especificada del objeto con valores animados. Para que ObjectAnimator funcione, el objeto debe tener un setter público para la propiedad que se está animando (por ejemplo, setTranslationX(float) para la propiedad "translationX").
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()
}
Propiedades de View compatibles: translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY, alpha, x, y, elevation. ObjectAnimator.ofFloat() se usa para propiedades float, ofInt() para int, ofObject() para tipos personalizados (color, punto). Para animación de color, use ofObject() con ArgbEvaluator o HsvEvaluator.
// ObjectAnimator con TypeEvaluator personalizado (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()
}
// Animando múltiples propiedades simultáneamente
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 — una interfaz para rastrear eventos de animación: onAnimationStart, onAnimationEnd, onAnimationCancel, onAnimationRepeat. Use AnimatorListenerAdapter para sobrescribir solo los métodos necesarios. A partir de Android 12, se agregó Animator.AnimationCallback con soporte para corrutinas mediante suspendAnimationFrame.
ValueAnimator es la clase base de Property Animation que genera valores animados desde el inicio hasta el final durante un tiempo determinado. A diferencia de ObjectAnimator, ValueAnimator no está vinculado a un objeto — simplemente calcula valores intermedios y notifica a través de un listener. El desarrollador decide qué hacer con los valores obtenidos: establecer una propiedad de View, cambiar un parámetro de Drawable, actualizar el dibujo personalizado en onDraw().
import android.animation.ValueAnimator
import android.view.animation.LinearInterpolator
"> ValueAnimator: animación del progreso de carga
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() — se usa para propiedades enteras (ancho, alto, número de pasos). ValueAnimator.ofObject() — para tipos personalizados con TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — para animación paralela de múltiples propiedades con un solo temporizador, ahorrando recursos en comparación con Animators separados para cada propiedad.
// ValueAnimator.ofObject con 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()
}
Rendimiento de ValueAnimator: a 60 FPS, onAnimationUpdate se llama cada ~16.7 ms. Evite dentro del listener: asignaciones de objetos (cree PointF/RectF una vez), llamar a findViewById(), cálculos pesados (E/S de archivos, red). Para animar 20+ elementos simultáneos, use PropertyValuesHolder en un Animator en lugar de 20 Animators separados. Para animaciones que cambian el tamaño, use View.setLayoutParams() solo al final de la animación (mediante AnimatorListenerAdapter.onAnimationEnd).
AnimatorSet es un orquestador que permite ejecutar múltiples instancias de Animator (ObjectAnimator, ValueAnimator) en un orden específico: secuencialmente (playSequentially), en paralelo (playTogether), con retrasos (after, before, with). AnimatorSet admite anidamiento — un AnimatorSet puede contener otros AnimatorSets para escenarios complejos.
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
// AnimatorSet: animación secuencial y paralela
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 {
// En paralelo: fadeIn + slideUp
play(fadeIn).with(slideUp)
"> Después: bounce con retardo de 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 proporciona una API fluida para construir cadenas: with() — en paralelo, before() — antes, after() — después. AnimatorSet admite cancel() para detener todas las animaciones del conjunto. Para escenarios complejos (25+ animadores), use PropertyValuesHolder — es más eficiente porque usa un solo temporizador compartido en lugar de uno separado para cada Animator.
| Método Builder | Descripción | Ejemplo |
|---|---|---|
| with(Animator) | Ejecutar en paralelo con la animación actual | play(fadeIn).with(slideUp) |
| before(Animator) | Animación actual antes de la especificada | play(fadeIn).before(bounce) |
| after(Animator) | Animación actual después de la especificada | play(bounce).after(slideUp) |
| after(Long) | Retraso antes de la animación actual | play(bounce).after(200L) |
Interpolator define la curva de velocidad de la animación de 0 a 1. Android proporciona Interpolators incorporados: LinearInterpolator (uniforme), AccelerateDecelerateInterpolator (lento-rápido-lento), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (con sobrepaso), BounceInterpolator (con rebote), AnticipateOvershootInterpolator (con retroceso antes de comenzar y sobrepaso del objetivo). El Interpolator personalizado se implementa mediante TimeInterpolator.
import android.animation.ObjectAnimator
import android.view.animation.BounceInterpolator
import android.view.animation.OvershootInterpolator
import android.view.animation.AnticipateOvershootInterpolator
// BounceInterpolator — efecto de rebote al final
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
duration = 600L
interpolator = BounceInterpolator()
start()
}
// AnticipateOvershoot — retroceso, luego sobrepaso
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
duration = 500L
interpolator = AnticipateOvershootInterpolator(2.0f)
start()
}
TypeEvaluator — una interfaz con el método evaluate(fraction, startValue, endValue) que calcula el valor intermedio entre inicio y fin. Integrados: ArgbEvaluator (color int), FloatEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator. Para tipos de datos personalizados (por ejemplo, animar una clase personalizada con tres campos), implemente su propio TypeEvaluator. Para animar múltiples Views con la misma configuración, use PropertyValuesHolder — acepta una matriz de nombres de propiedad y valores correspondientes.
// TypeEvaluator personalizado para la clase 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 — máximo rendimiento
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()
}
Preguntas frecuentes
View Animation (Tween Animation) cambia solo la representación visual de una View a través de una transformación de matriz, sin afectar las propiedades reales del objeto. Después de una animación de translationX en View Animation, el elemento se desplaza visualmente, pero los clics aún se procesan en la posición original. Property Animation (ObjectAnimator) cambia la propiedad real — después de la animación, el elemento está físicamente en la nueva posición.
Llame a animator.cancel() — la animación se detiene inmediatamente, el valor final no se aplica. Llamar a animator.end() — la animación pasa al estado final y se detiene. Para AnimatorSet — set.cancel() detiene todas las animaciones del conjunto. Animator.pause() y resume() están disponibles en API 19+ para pausa temporal.
Material Design recomienda: FastOutSlowInInterpolator — para animaciones de aparición y desaparición de elementos, LinearInterpolator — para indicadores de carga, OvershootInterpolator — para efectos de acento (botones), BounceInterpolator — para pull-to-refresh y elementos elásticos. Para animaciones que aparecen desde fuera de la pantalla, use AccelerateDecelerateInterpolator.
Verifique: (1) el objeto tiene un setter público para la propiedad especificada (setPropertyName()), (2) la propiedad está escrita en camelCase con minúscula después de "set", (3) el setter acepta el mismo tipo que está pasando (ofFloat → setPropertyName(float)). Para View, todas las propiedades estándar (alpha, translationX, rotation, etc.) tienen setters.
ObjectAnimator — cuando anima una propiedad estándar única de View (alpha, translationX, rotation). ValueAnimator — cuando necesita actualizar múltiples propiedades desde un listener, animar propiedades que no son de View (progreso, dibujo personalizado), o cuando el objeto no tiene un setter para la propiedad requerida. ValueAnimator es más flexible pero requiere más código para actualizaciones manuales.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también