Cómo mover una vista con animación

A menudo, es necesario reposicionar los objetos que aparecen en pantalla. Puede deberse a la interacción del usuario o el procesamiento detrás de escena. En lugar de actualizar inmediatamente la posición de los objetos, lo que haría que parpadeara de un área a otra, debes usar una animación para moverlo de la posición inicial a su posición final.

Android ofrece maneras que te permiten reposicionar tus objetos de visualización, como el ObjectAnimator. Puedes indicar la posición final en la que deseas colocar el objeto, además de la duración de la animación. Combina estos datos con los interpoladores de tiempo a fin de 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 te proporciona una manera fácil 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 reposiciones tus vistas en la pantalla, debes usar los atributos translationX y translationY.

A continuación, puedes ver un ejemplo de un ObjectAnimator que mueve la vista 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 deseas animar. El segundo parámetro es la propiedad que estás animando. Como la vista debe moverse de forma horizontal, se utiliza la propiedad translationX. El último parámetro es el valor final de la animación. Como este valor es de 100, se moverán 100 píxeles desde la izquierda de la pantalla.

En el siguiente método, se especifica cuánto debería tardar la animación en milésimas de segundos. En este ejemplo, se ejecutará la animación durante 2 segundos (200 milésimas de segundos).

El último método hace que se ejecute la animación, lo que actualizará 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 usarlo, ObjectAnimator reposicionará la vista de manera predeterminada usando una línea recta entre los puntos de inicio y de finalización. Material design usa curvas, no solo para el tiempo de una animación, sino también para el movimiento espacial de los objetos en la pantalla. Usa movimientos curvos para brindarle a tu app mayor sensación de realidad y, al mismo tiempo, lograr que tus animaciones sean más interesantes.

Cómo usar PathInterpolator

La clase PathInterpolator es un interpolador nuevo que se introdujo en Android 5.0 (API 21). Se basa en una curva Bézier o un objeto Path. Este interpolador especifica una curva de movimiento en un cuadrado de 1 x 1, con puntos de anclaje en (0,0) y (1,1) y puntos de control según lo especificado con los argumentos del constructor. Una forma de crear un PathInterpolator consiste en crear un objeto Path y proporcionárselo al PathInterpolator:

Kotlin

    // arcTo() and PathInterpolator only available on API 21+
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        val path = Path().apply {
            arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true)
        }
        val pathInterpolator = PathInterpolator(path)
    }

    

Java

    // arcTo() and PathInterpolator only available on API 21+
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      Path path = new Path();
      path.arcTo(0f, 0f, 1000f, 1000f, 270f, -180f, true);
      PathInterpolator pathInterpolator = new PathInterpolator(path);
    }

    

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.4"
        android:controlY1="0"
        android:controlX2="1"
        android:controlY2="1"/>
    

Una vez que hayas creado un objeto PathInterpolator, puedes pasárselo al método Animator.setInterpolator(). Luego, el animador usará el interpolador a fin de determinar la curva de la trayectoria o el tiempo cuando se lo inicia.

Kotlin

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

    

Java

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

    

Cómo definir tu propia trayectoria

La clase ObjectAnimator tiene constructores nuevos que te permiten animar las coordenadas a lo largo de una trayectoria usando dos o más propiedades a la vez. 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:

Si no deseas crear tus propias curvas de trayectoria o 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