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