Spostare una visualizzazione con animazione

Prova Compose
Jetpack Compose è il toolkit UI consigliato per Android. Scopri come utilizzare le animazioni in Compose.

Spesso è necessario riposizionare gli oggetti sullo schermo a causa dell'interazione dell'utente o dell'elaborazione in background. Invece di aggiornare immediatamente la posizione dell'oggetto, che lo fa lampeggiare da un'area all'altra, utilizza un'animazione per spostarlo dalla posizione iniziale a quella finale.

Un modo in cui Android ti consente di riposizionare gli oggetti della visualizzazione sullo schermo è utilizzando ObjectAnimator. Fornisci la posizione finale in cui vuoi che l'oggetto si stabilizzi, nonché la durata dell'animazione. Puoi anche utilizzare gli interpolatori di tempo per controllare l'accelerazione o la decelerazione dell'animazione.

Modificare la posizione della visualizzazione con ObjectAnimator

L'ObjectAnimator API fornisce 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 riposizioni 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 dal bordo sinistro 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 ObjectAnimator.ofFloat() metodo, perché i valori di traslazione devono essere float. Il primo parametro è la visualizzazione che vuoi animare. Il secondo parametro è la proprietà che stai animando. Poiché la visualizzazione deve spostarsi orizzontalmente, viene utilizzata la proprietà translationX. L'ultimo parametro è il valore finale dell'animazione. In questo esempio, il valore 100 indica una posizione a molti pixel dal bordo sinistro dello schermo.

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

L'ultimo metodo fa partire l'animazione, che aggiorna la posizione della visualizzazione sullo schermo.

Per saperne di più sull'utilizzo di ObjectAnimator, consulta Animare utilizzando ObjectAnimator.

Aggiungere movimento curvo

Sebbene l'utilizzo di ObjectAnimator sia pratico, per impostazione predefinita riposiziona la visualizzazione lungo una linea retta tra i punti di inizio e di fine. Material Design si basa su curve per il movimento spaziale degli oggetti sullo schermo e la tempistica di un'animazione. L'utilizzo di un movimento curvo conferisce alla tua app un aspetto più materiale e rende le animazioni più interessanti.

Definire il proprio percorso

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

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 l'aspetto dell'animazione dell'arco:

Figura 1. Un'animazione del percorso curvo.

Un Interpolator è un'implementazione di una curva di easing. Per saperne di più sul concetto di curve di easing, consulta la documentazione di Material Design. Un Interpolator definisce il modo in cui vengono calcolati valori specifici in un'animazione in 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

Utilizzare PathInterpolator

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

PathInterpolator ha costruttori basati su diversi tipi di curve di Bézier. Tutte le curve di Bézier hanno punti di inizio e di fine fissati rispettivamente a (0,0) e (1,1). Gli altri argomenti del costruttore dipendono dal tipo di curva di Bézier che viene 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();
}

In questo modo si ottiene una curva di easing che inizia rapidamente e decelera man mano che si avvicina alla 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 emphasized decelerate 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();
}

In questo modo si ottiene la stessa curva di easing dell'esempio di Bézier cubico, ma viene utilizzato 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 Animator.setInterpolator() metodo. Quando viene avviato, Animator utilizza l'interpolatore per determinare la curva di tempistica o di percorso.

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();