Punti chiave
Interpolator — un'interfaccia in Android che mappa il valore frazionario dell'avanzamento dell'animazione (da 0.0 a 1.0) a un valore effettivo con velocità modificata. Se un'animazione dura 300 millisecondi, il sistema chiama Interpolator per ogni fotogramma, passando l'avanzamento corrente. Interpolator restituisce un valore modificato — ad esempio, con AccelerateInterpolator al 50% del tempo l'animazione ha percorso solo circa il 25% del percorso, simulando l'accelerazione.
Matematicamente, Interpolator può essere rappresentato come una funzione f(t), dove t è il tempo normalizzato [0, 1] e f(t) è il valore normalizzato [0, 1] (o più ampio per Overshoot/Bounce). LinearInterpolator restituisce f(t) = t — l'oggetto si muove a velocità costante. AccelerateInterpolator approssima f(t) = t², DecelerateInterpolator approssima f(t) = 1 − (1 − t)², creando un inizio o una fine fluidi. In Android Animation Framework, Interpolator viene applicato sia a ValueAnimator, ObjectAnimator e ViewPropertyAnimator, fornendo un approccio unificato al controllo della velocità a tutti i livelli.
Android offre 9 interpolatori integrati, ciascuno con il proprio modello matematico. La scelta dell'interpolatore determina il carattere dell'animazione: fisicità (Bounce), elasticità (Overshoot) o fluidità (AccelerateDecelerate).
| Interpolatore | Matematica | Caso d'uso |
|---|---|---|
| LinearInterpolator | f(t) = t | Indicatori di progresso, testo scorrevole |
| AccelerateInterpolator | f(t) = tⁿ (n=2) | Elemento che esce dallo schermo, appare dal basso |
| DecelerateInterpolator | f(t) = 1 − (1 − t)ⁿ | Oggetto che cade, entrata dall'alto con decelerazione |
| AccelerateDecelerateInterpolator | Approssimazione cos | Universale, comparsa/scomparsa di elementi |
| AnticipateInterpolator | Cubica con arretramento | Ingresso elastico — l'oggetto arretra leggermente prima di iniziare |
| OvershootInterpolator | Cubica con superamento | Pulsante di azione — supera leggermente la posizione target |
| AnticipateOvershootInterpolator | Combinazione di Anticipate + Overshoot | Carte — arretramento + superamento con ritorno |
| BounceInterpolator | Rimbalzi smorzati | Palla, elemento che cade su una superficie |
| PathInterpolator | Bézier cubica (2 punti di controllo) | Curve personalizzate per il sistema di design |
Ogni interpolatore ha una dichiarazione XML in res/interpolator/ e una classe Kotlin nel pacchetto android.view.animation. AccelerateDecelerateInterpolator è il più utilizzato: la sua curva ricorda la funzione di easing ease-in-out in CSS. Per le applicazioni Android con Material Design, si consiglia OvershootInterpolator per i pulsanti di azione flottante (FAB) — crea un effetto di rimbalzo quando appare.
PathInterpolator — un interpolatore basato su una curva di Bézier, definito tramite un oggetto Path. Disponibile dall'API 21 (Android 5.0). Consente di progettare visivamente la curva di velocità — il designer disegna la curva, lo sviluppatore la trasferisce nel codice attraverso le coordinate dei punti di controllo. È supportata solo la Bézier cubica (due punti di controllo C1, C2).
La curva di PathInterpolator inizia sempre nel punto (0,0) e termina in (1,1). I punti di controllo definiscono la forma: (x1, y1) — il punto iniziale, (x2, y2) — il punto finale. I valori x devono essere nell'intervallo [0,1] — questo garantisce la monotonicità nel tempo. I valori y possono uscire da [0,1] — questo crea un effetto di superamento o anticipazione. Ad esempio, il Material Design standard utilizza la curva fast-out-slow-in con punti di controllo (0.4, 0.0, 0.2, 1.0). In IT Sectr costruiamo PathInterpolators personalizzati per ogni sistema di design — questo garantisce animazioni coerenti su tutti gli schermi.
Se gli interpolatori integrati non coprono il tuo scenario, Android consente di crearne uno personalizzato implementando l'interfaccia TimeInterpolator. L'unico metodo è getInterpolation(input: Float): Float. Input è l'avanzamento corrente dell'animazione da 0 a 1; output è il valore modificato. Output può uscire da [0,1] per effetti di superamento o rimbalzo.
Interpolatori personalizzati tipici: effetto di rimbalzo smorzato (superamento di 1.0 e ritorno), effetto elastico (smorzamento sinusoidale), interpolatore a gradino (salti discreti). Gli interpolatori personalizzati possono anche essere definiti tramite XML usando il tag <interpolator> e specificando la classe. Android Studio ha un'anteprima integrata di Interpolator in Layout Inspector — mostra la curva effettiva per l'interpolatore selezionato, semplificando il debug.
Animazione di base della scala di un pulsante utilizzando un interpolatore simmetrico. ValueAnimator cambia il valore da 1.0 a 1.2 e viceversa, e AccelerateDecelerateInterpolator rende il movimento fluido.
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.View
fun View.pulseAnimation() {
ValueAnimator.ofFloat(1.0f, 1.2f).apply {
duration = 300
interpolator = AccelerateDecelerateInterpolator()
repeatCount = 1
repeatMode = ValueAnimator.REVERSE
addUpdateListener { animator ->
val scale = animator.animatedValue as Float
this@pulseAnimation.scaleX = scale
this@pulseAnimation.scaleY = scale
}
start()
}
}
AccelerateDecelerateInterpolator crea un'accelerazione fluida all'inizio e una decelerazione fluida alla fine. La modalità REVERSE ripete l'animazione nella direzione opposta, creando un effetto di pulsazione. Questo modello viene utilizzato per i pulsanti di azione, attirando l'attenzione dell'utente su un elemento chiave dell'interfaccia.
Curva personalizzata con effetto di superamento — l'oggetto supera la posizione target del 10% e ritorna. I punti di controllo (0.4, 0.0, 0.6, 1.3) definiscono un ingresso accelerato con superamento.
import android.animation.ObjectAnimator
import android.graphics.Path
import android.view.animation.PathInterpolator
import android.view.View
fun View.slideWithOvershoot() {
val path = Path().apply {
cubicTo(0.4f, 0.0f, 0.6f, 1.3f, 1.0f, 1.0f)
}
val interpolator = PathInterpolator(path)
ObjectAnimator.ofFloat(this, "translationY", 200f, 0f).apply {
duration = 400
interpolator = interpolator
start()
}
}
PathInterpolator accetta un Path con una curva di Bézier cubica. Nell'esempio, l'elemento supera la posizione target (y=1.3 al 60% del tempo) e ritorna alla posizione finale. Il Path deve essere strettamente monotono lungo l'asse x, altrimenti l'animazione andrà all'indietro. Per la verifica, utilizzare Layout Inspector in Android Studio.
Interpolatore personalizzato con effetto di rimbalzo smorzato. Implementazione tramite TimeInterpolator con quattro cicli di smorzamento.
import android.animation.TimeInterpolator
class DampedBounceInterpolator : TimeInterpolator {
private val cycles = 4
private val damping = 0.85f
override fun getInterpolation(input: Float): Float {
val t = input * cycles
val decay = Math.pow(damping.toDouble(), cycles.toDouble()).toFloat()
val peak = t - (Math.floor(t.toDouble())).toFloat()
val bounce = Math.sin(peak * Math.PI).toFloat()
return 1f - bounce * decay * (1f - input)
}
}
L'interpolatore personalizzato DampedBounceInterpolator crea 4 rimbalzi smorzati con un coefficiente di smorzamento di 0,85. Il metodo getInterpolation prende un input lineare e restituisce un valore con effetto molla. In IT Sectr utilizziamo questo interpolatore per l'animazione di comparsa delle notifiche — il rimbalzo crea una sensazione di fisicità e attira l'attenzione.
Domande frequenti
AccelerateDecelerateInterpolator crea una curva simmetrica — l'oggetto accelera all'inizio e decelera alla fine. PathInterpolator consente di specificare una curva arbitraria tramite Path con un punto di controllo (Bézier cubica). Per animazioni personalizzate con comportamento asimmetrico (ad esempio, inizio rapido + fine lenta), utilizzare PathInterpolator con punti di controllo (0.2, 0.8, 0.4, 1.0).
Sì, implementa l'interfaccia TimeInterpolator e sovrascrivi il metodo getInterpolation(input: Float): Float. Input è un valore frazionario da 0 a 1 (avanzamento dell'animazione), output è il valore effettivo. Ad esempio, un effetto di rimbalzo viene implementato restituendo valori maggiori di 1 o minori di 0 per un comportamento elastico. Registra l'interpolatore tramite il tag XML
PathInterpolator è stato aggiunto nell'API 21 (Android 5.0 Lollipop). Per le versioni precedenti, utilizzare AccelerateDecelerateInterpolator o un TimeInterpolator personalizzato. PathInterpolator supporta solo curve di Bézier cubiche con due punti di controllo — linee rette e curve quadratiche possono produrre interpolazione errata. Per la retrocompatibilità, utilizzare AccelerateDecelerateInterpolator come fallback.
Material Design 3 raccomanda la curva fast-out-slow-in con punti di controllo (0.4, 0.0, 0.2, 1.0) per la comparsa degli elementi, linear-out-slow-in (0.0, 0.0, 0.2, 1.0) per la scomparsa e fast-out-linear-in (0.4, 0.0, 1.0, 1.0) per il movimento. In Android queste curve sono implementate nella classe FastOutSlowInInterpolator della libreria Material Components.
Minimamente. Gli interpolatori integrati eseguono un'operazione matematica per fotogramma — il sovraccarico è trascurabile. Gli interpolatori personalizzati con calcoli pesanti (trigonometria, cicli) possono causare micro-jank su dispositivi deboli. Ottimizza precalcolando i valori nel costruttore o utilizza TimeInterpolator con caching.
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