Cómo mover una vista con animación

Prueba el método de Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Aprende a usar animaciones en Compose.

A menudo, es necesario reposicionar los objetos que aparecen en pantalla debido a la interacción del usuario o el procesamiento en segundo plano. En lugar de actualizar de inmediato la posición del objeto, lo que hace que parpadee de un área a otra, usa una animación para moverlo de la posición inicial a la posición final.

Una forma en que Android te permite reposicionar tus objetos de vista en la pantalla es con ObjectAnimator. Proporcionas la posición final en la que deseas que se acomode el objeto, así como la duración de la animación. También puedes usar interpoladores de tiempo para controlar la aceleración o desaceleración de la animación.

Cómo cambiar la posición de la vista con ObjectAnimator

La API de ObjectAnimator proporciona una forma de cambiar las propiedades de una vista con una duración especificada. Contiene métodos estáticos para crear instancias de ObjectAnimator, según el tipo de atributo que estás animando. Cuando cambies la posición de las vistas en la pantalla, usa los atributos translationX y translationY.

A continuación, puedes ver un ejemplo de un ObjectAnimator que mueve la vista a una posición 100 píxeles desde la izquierda de la pantalla en 2 segundos:

Kotlin

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

Java

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

En este ejemplo, se usa el método ObjectAnimator.ofFloat(), ya que los valores de traducción tienen que ser flotantes. El primer parámetro es la vista que quieres animar. El segundo parámetro es la propiedad que estás animando. Como la vista debe moverse horizontalmente, se usa la propiedad translationX. El último parámetro es el valor final de la animación. En este ejemplo, el valor de 100 indica una posición que está a muchos píxeles de la izquierda de la pantalla.

En el siguiente método, se especifica cuánto tiempo tarda la animación, en milisegundos. En este ejemplo, la animación se ejecuta durante 2 segundos (2,000 milisegundos).

El último método hace que se ejecute la animación, lo que actualiza la posición de la vista en la pantalla.

Para obtener más información sobre el uso de ObjectAnimator, consulta Cómo animar con ObjectAnimator.

Cómo agregar movimientos curvos

Si bien conviene usar ObjectAnimator, este reposiciona la vista de forma predeterminada en una línea recta entre los puntos de inicio y finalización. Material Design se basa en curvas para el movimiento espacial de los objetos en la pantalla y el tiempo de una animación. El uso de movimientos curvos le brinda a tu app una sensación de material más material y, al mismo tiempo, hace que tus animaciones sean más interesantes.

Cómo definir tu propia trayectoria

La clase ObjectAnimator tiene constructores que te permiten animar coordenadas con dos o más propiedades a la vez junto con una ruta. Por ejemplo, el siguiente animador usa un objeto Path para animar las propiedades X e Y de 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
}

La animación de arco se ve de la siguiente manera:

Figura 1: Una animación de ruta curva.

Un Interpolator es una implementación de una curva de suavización. Consulta la documentación de Material Design para obtener más información sobre el concepto de curvas de suavización. Un Interpolator define cómo se calculan los valores específicos de una animación en función del tiempo. El sistema proporciona recursos XML para las tres curvas básicas en la especificación de Material Design:

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

Cómo usar PathInterpolator

La clase PathInterpolator es un interpolador que se introdujo en Android 5.0 (nivel de API 21). Se basa en una curva Bézier o un objeto Path. Los ejemplos de Android en la documentación de Material Design sobre la aceleración del uso de PathInterpolator

PathInterpolator tiene constructores basados en diferentes tipos de curvas Bézier. Todas las curvas Bézier tienen puntos de inicio y finalización fijos en (0,0) y (1,1), respectivamente. Los otros argumentos del constructor dependen del tipo de curva Bézier que se cree.

Por ejemplo, para una curva Bézier cuadrática, solo se necesitan las coordenadas X e Y de un punto de control:

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

Esto produce una curva de aceleración que comienza rápidamente y se desacelera a medida que se acerca al final.

De manera similar, el constructor cúbico Bézier estableció los puntos de inicio y finalización, pero requiere dos puntos de control:

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

Esta es una implementación de la curva de aceleración enfatizada de Material Design.

Para obtener un mayor control, se puede usar un Path arbitrario para definir 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();
}

Esto produce la misma curva de aceleración que el ejemplo de Bézier cúbico, pero utiliza un Path en su lugar.

También puedes definir un interpolador para la trayectoria como un recurso 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"/>

Una vez que crees un objeto PathInterpolator, puedes pasarlo al método Animator.setInterpolator(). Animator usa el interpolador para determinar la curva de la trayectoria o el tiempo cuando se lo inicia.

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