Spostare una visualizzazione con animazione

Prova la funzionalità Scrivi
Jetpack Compose è il toolkit consigliato per la UI per Android. Scopri come utilizzare le animazioni in Scrittura.

Gli oggetti sullo schermo spesso devono essere riposizionati a causa dell'interazione dell'utente o dell'elaborazione in background. Anziché aggiornare immediatamente la posizione dell'oggetto, facendolo lampeggiare da un'area all'altra, utilizza un'animazione per spostarlo dalla posizione iniziale alla posizione finale.

Un modo in cui Android consente di riposizionare gli oggetti delle visualizzazioni sullo schermo è utilizzare ObjectAnimator. Specifica la posizione finale in cui vuoi posizionare l'oggetto e la durata dell'animazione. Puoi anche utilizzare interpolatori temporali per controllare l'accelerazione o la decelerazione dell'animazione.

Modificare la posizione della vista con ObjectAnimator

L'API ObjectAnimator offre un modo per modificare le proprietà di una visualizzazione con una durata specificata. Contiene metodi statici per creare istanze di ObjectAnimator a seconda del tipo di attributo che stai animando. Quando riposiziona le visualizzazioni sullo schermo, utilizza gli attributi translationX e translationY.

Ecco un esempio di ObjectAnimator che sposta la visualizzazione in una posizione a 100 pixel a sinistra dello schermo in 2 secondi:

Kotlin

ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    duration = 2000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setDuration(2000);
animation.start();

Questo esempio utilizza il metodo ObjectAnimator.ofFloat() , perché i valori di traduzione devono essere numeri in virgola mobile. Il primo parametro è la vista che vuoi animare. Il secondo parametro è la proprietà che stai animando. Poiché la vista deve spostarsi in orizzontale, viene utilizzata la proprietà translationX. L'ultimo parametro è il valore di fine dell'animazione. In questo esempio, il valore 100 indica una posizione a molti pixel a sinistra dello schermo.

Il metodo successivo specifica la durata dell'animazione, in millisecondi. In questo esempio, l'animazione viene eseguita per 2 secondi (2000 millisecondi).

L'ultimo metodo determina l'esecuzione dell'animazione, che aggiorna la posizione della visualizzazione sullo schermo.

Per ulteriori informazioni sull'utilizzo di ObjectAnimator, consulta Creare animazioni con ObjectAnimator.

Aggiungi movimento curvo

L'utilizzo di ObjectAnimator è pratico, ma per impostazione predefinita riposiziona la visualizzazione lungo una linea retta tra i punti iniziale e finale. Il material design si basa sulle curve per il movimento spaziale degli oggetti sullo schermo e la tempistica di un'animazione. L'utilizzo dei movimenti curvi conferisce all'app un aspetto più matematico e rende le animazioni più interessanti.

Definisci il tuo percorso

La classe ObjectAnimator ha dei costruttori che ti consentono di animare le coordinate utilizzando contemporaneamente due o più proprietà insieme a un percorso. Ad esempio, il seguente animatore utilizza un oggetto Path per animare le proprietà X e Y di una vista:

Kotlin

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    val path = Path().apply {
        arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true)
    }
    val animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path).apply {
        duration = 2000
        start()
    }
} else {
    // Create animator without using curved path
}

Java

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
  ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
  animator.setDuration(2000);
  animator.start();
} else {
  // Create animator without using curved path
}

Ecco come appare l'animazione dell'arco:

Figura 1. Un'animazione con percorso curvo.

Una Interpolator è un'implementazione di una curva di easing. Consulta la documentazione di Material Design per ulteriori informazioni sul concetto di curve di easing. Un Interpolator definisce il modo in cui valori specifici in un'animazione vengono calcolati come funzione del tempo. Il sistema fornisce risorse XML per le tre curve di base nella specifica di Material Design:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

Utilizzo di PathInterpolator

La classe PathInterpolator è un interpolatore introdotto in Android 5.0 (API 21). Si basa su una curva di Bézier o su un oggetto Path. Gli esempi per Android nella documentazione di Material Design per le animazioni utilizzano PathInterpolator.

PathInterpolator ha costruttori basati su diversi tipi di curve di Bézier. Tutti i punti di inizio e di fine delle curve di Bézier sono fissati rispettivamente su (0,0) e (1,1). Gli altri argomenti del costruttore dipendono dal tipo di curva di Bézier creata.

Ad esempio, per una curva di Bézier quadratica sono necessarie solo le coordinate X e Y di un punto di controllo:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.67f, 0.33f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.67f, 0.33f);
} else {
  myInterpolator = new LinearInterpolator();
}

Questo produce una curva di easing che inizia rapidamente e si rallenta man mano che si avvicina la fine.

Analogamente, il costruttore di Bézier cubico ha punti di inizio e di fine fissi, ma richiede due punti di controllo:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f)
} else {
    LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  myInterpolator = new PathInterpolator(0.5f, 0.7f, 0.1f, 1.0f);
} else {
  myInterpolator = new LinearInterpolator();
}

Si tratta di un'implementazione della curva di easing con enfatizzazione della decelerazione di Material Design.

Per un maggiore controllo, è possibile utilizzare un Path arbitrario per definire la curva:

Kotlin

val myInterpolator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  val path = Path().apply {
    moveTo(0.0f, 0.0f)
    cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f)
  }
  PathInterpolator(path)
} else {
  LinearInterpolator()
}

Java

Interpolator myInterpolator = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
  Path path = new Path();
  path.moveTo(0.0f, 0.0f);
  path.cubicTo(0.5f, 0.7f, 0.1f, 1.0f, 1.0f, 1.0f);
  myInterpolator = new PathInterpolator(path);
} else {
  myInterpolator = new LinearInterpolator();
}

Questo produce la stessa curva di easing dell'esempio di Bézier cubico, ma utilizza invece un Path.

Puoi anche definire un interpolatore di percorso come risorsa XML:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.5"
    android:controlY1="0.7"
    android:controlX2="0.1f"
    android:controlY2="1.0f"/>

Dopo aver creato un oggetto PathInterpolator, puoi passarlo al metodo Animator.setInterpolator(). Animator utilizza l'interpolatore per determinare il tempo o la curva del percorso quando viene avviato.

Kotlin

val animation = ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    interpolator = myInterpolator
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 100f);
animation.setInterpolator(myInterpolator);
animation.start();