Property Animation è un sistema di animazione in Android, introdotto in Android 3.0 (API 11), che modifica le proprietà reali degli oggetti (non solo View) per un periodo di tempo specificato. A differenza della legacy View Animation, Property Animation cambia i campi effettivi dell'oggetto — coordinate, dimensione, trasparenza, colore — e non solo la rappresentazione visiva. Secondo Google Android Developers (2026), Property Animation è utilizzata nell'89% delle app Android della top 100. Scopri di più sugli altri tipi di animazione nella guida generale all'animazione.
Punti chiave
Property Animation è un framework in Android SDK (pacchetto android.animation) che anima qualsiasi proprietà di qualsiasi oggetto (View, Drawable, classe personalizzata) per un tempo specificato. A differenza di View Animation, che funziona solo con View e modifica solo la rappresentazione visiva (trasformazione di matrice), Property Animation modifica i campi reali dell'oggetto. Ciò significa che dopo un'animazione translationX, l'oggetto si trova effettivamente nella nuova posizione e i clic vengono elaborati nella nuova posizione.
L'architettura di Property Animation è costruita su tre classi chiave: ValueAnimator — il generatore di valori di base, ObjectAnimator — una sottoclasse per legarsi a una proprietà dell'oggetto, AnimatorSet — un orchestratore per l'animazione di gruppo. Tutte e tre supportano Interpolator (curva di velocità) e TypeEvaluator (regola di interpolazione tra valori).
Secondo Android Performance Patterns (Google, 2025), Property Animation funziona fino a 60 FPS con un Interpolator configurato correttamente e senza calcoli pesanti in onAnimationUpdate(). Per animazioni complesse (3D, fisica), si consiglia RenderThread (RenderNode Animations) in Android 12+. Property Animation rimane la scelta principale per animare le proprietà di View — translationX, rotationY, scaleX, alpha e altre.
ObjectAnimator è la classe più popolare di Property Animation. Estende ValueAnimator e chiama automaticamente il setter della proprietà specificata dell'oggetto con valori animati. Affinché ObjectAnimator funzioni, l'oggetto deve avere un setter pubblico per la proprietà che si sta animando (ad esempio, setTranslationX(float) per la proprietà “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()
}
Proprietà di View supportate: translationX, translationY, translationZ, rotation, rotationX, rotationY, scaleX, scaleY, alpha, x, y, elevation. ObjectAnimator.ofFloat() viene utilizzato per le proprietà float, ofInt() per int, ofObject() per i tipi personalizzati (colore, punto). Per l'animazione del colore, usa ofObject() con ArgbEvaluator o HsvEvaluator.
// ObjectAnimator con TypeEvaluator personalizzato (colore)
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()
}
// Animare più proprietà simultaneamente
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 — un'interfaccia per tracciare gli eventi di animazione: onAnimationStart, onAnimationEnd, onAnimationCancel, onAnimationRepeat. Usa AnimatorListenerAdapter per sovrascrivere solo i metodi necessari. A partire da Android 12, è stato aggiunto Animator.AnimationCallback con supporto per le coroutine tramite suspendAnimationFrame.
ValueAnimator è la classe base di Property Animation che genera valori animati dall'inizio alla fine per un periodo di tempo determinato. A differenza di ObjectAnimator, ValueAnimator non è legato a un oggetto — calcola semplicemente i valori intermedi e notifica tramite un listener. Lo sviluppatore decide cosa fare con i valori ottenuti: impostare una proprietà di View, cambiare un parametro di Drawable, aggiornare il disegno personalizzato in onDraw().
import android.animation.ValueAnimator
import android.view.animation.LinearInterpolator
"> ValueAnimator: animazione del progresso di caricamento
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() — utilizzato per le proprietà intere (larghezza, altezza, numero di passi). ValueAnimator.ofObject() — per i tipi personalizzati con TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — per l'animazione parallela di più proprietà con un singolo timer, risparmiando risorse rispetto ad Animator separati per ogni proprietà.
// 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()
}
Prestazioni di ValueAnimator: a 60 FPS, onAnimationUpdate viene chiamato ogni ~16,7 ms. Evita all'interno del listener: allocazioni di oggetti (crea PointF/RectF una volta), chiamate a findViewById(), calcoli pesanti (I/O file, rete). Per animare 20+ elementi simultaneamente, usa PropertyValuesHolder in un singolo Animator invece di 20 Animator separati. Per animazioni con cambio di dimensione, usa View.setLayoutParams() solo alla fine dell'animazione (tramite AnimatorListenerAdapter.onAnimationEnd).
AnimatorSet è un orchestratore che consente di eseguire più istanze di Animator (ObjectAnimator, ValueAnimator) in un ordine specifico: sequenzialmente (playSequentially), in parallelo (playTogether), con ritardi (after, before, with). AnimatorSet supporta l'annidamento — un AnimatorSet può contenere altri AnimatorSet per scenari complessi.
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
// AnimatorSet: animazione sequenziale e parallela
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 parallelo: fadeIn + slideUp
play(fadeIn).with(slideUp)
"> Dopo: bounce con ritardo di 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 fornisce un'API fluente per costruire catene: with() — in parallelo, before() — prima, after() — dopo. AnimatorSet supporta cancel() per fermare tutte le animazioni nel set. Per scenari complessi (25+ animatori), usa PropertyValuesHolder — è più performante perché utilizza un singolo timer condiviso invece di uno separato per ogni Animator.
| Metodo Builder | Descrizione | Esempio |
|---|---|---|
| with(Animator) | Esegui in parallelo con l'animazione corrente | play(fadeIn).with(slideUp) |
| before(Animator) | Animazione corrente prima di quella specificata | play(fadeIn).before(bounce) |
| after(Animator) | Animazione corrente dopo quella specificata | play(bounce).after(slideUp) |
| after(Long) | Ritardo prima dell'animazione corrente | play(bounce).after(200L) |
Interpolator definisce la curva di velocità dell'animazione da 0 a 1. Android fornisce Interpolator integrati: LinearInterpolator (uniforme), AccelerateDecelerateInterpolator (lento-veloce-lento), FastOutSlowInInterpolator (Material Design), OvershootInterpolator (con superamento), BounceInterpolator (con rimbalzo), AnticipateOvershootInterpolator (con arretramento prima dell'inizio e superamento del bersaglio). Un Interpolator personalizzato viene implementato tramite TimeInterpolator.
import android.animation.ObjectAnimator
import android.view.animation.BounceInterpolator
import android.view.animation.OvershootInterpolator
import android.view.animation.AnticipateOvershootInterpolator
// BounceInterpolator — effetto rimbalzo alla fine
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
duration = 600L
interpolator = BounceInterpolator()
start()
}
// AnticipateOvershoot — arretramento, poi superamento
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
duration = 500L
interpolator = AnticipateOvershootInterpolator(2.0f)
start()
}
TypeEvaluator — un'interfaccia con il metodo evaluate(fraction, startValue, endValue) che calcola il valore intermedio tra inizio e fine. Integrati: ArgbEvaluator (colore int), FloatEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator. Per tipi di dati personalizzati (ad esempio, animare una classe personalizzata con tre campi), implementa il tuo TypeEvaluator. Per animare più View con le stesse impostazioni, usa PropertyValuesHolder — accetta un array di nomi di proprietà e valori corrispondenti.
// TypeEvaluator personalizzato per la classe 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 — massime prestazioni
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()
}
Domande frequenti
View Animation (Tween Animation) modifica solo la rappresentazione visiva di una View attraverso una trasformazione di matrice, senza influenzare le proprietà reali dell'oggetto. Dopo un'animazione translationX in View Animation, l'elemento viene spostato visivamente, ma i clic vengono ancora elaborati nella posizione originale. Property Animation (ObjectAnimator) modifica la proprietà reale — dopo l'animazione, l'elemento si trova fisicamente nella nuova posizione.
Chiama animator.cancel() — l'animazione si ferma immediatamente, il valore finale non viene applicato. Chiamare animator.end() — l'animazione passa allo stato finale e si ferma. Per AnimatorSet — set.cancel() ferma tutte le animazioni nel set. Animator.pause() e resume() sono disponibili su API 19+ per la pausa temporanea.
Material Design raccomanda: FastOutSlowInInterpolator — per animazioni di apparizione e scomparsa degli elementi, LinearInterpolator — per gli indicatori di caricamento, OvershootInterpolator — per effetti di accento (pulsanti), BounceInterpolator — per pull-to-refresh ed elementi elastici. Per le animazioni che appaiono da fuori schermo, usa AccelerateDecelerateInterpolator.
Verifica: (1) l'oggetto ha un setter pubblico per la proprietà specificata (setPropertyName()), (2) la proprietà è scritta in camelCase con una lettera minuscola dopo “set”, (3) il setter accetta lo stesso tipo che stai passando (ofFloat → setPropertyName(float)). Per View, tutte le proprietà standard (alpha, translationX, rotation, ecc.) hanno setter.
ObjectAnimator — quando stai animando una singola proprietà standard di View (alpha, translationX, rotation). ValueAnimator — quando devi aggiornare più proprietà da un unico listener, animare proprietà non View (progresso, disegno personalizzato), o quando l'oggetto non ha un setter per la proprietà richiesta. ValueAnimator è più flessibile ma richiede più codice per gli aggiornamenti manuali.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche