Animaciones en Android

1
15334

Índice de contenidos

1. Introducción

El objetivo de este tutorial es servir de introducción a las animaciones en Android. Para alguno de los tipos de animaciones se mostrarán ejemplos sencillos mientras que otros tan sólo se describirán brevemente.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: MacBook Pro 17’ (2,66 GHz Intel Core i7, 8GB DDR3)
  • Sistema operativo: macOS Sierra 10.13.6
  • Entorno de desarrollo: Android Studio 3.3
  • Versión SDK mínima: 21

3. El paquete Animation

Android proporciona varias formas para animar las vistas. El primer paquete que vamos a evaluar es Animation, el cual se utiliza para animaciones simples. En él podemos encontrar las siguientes subclases:

  • AlphaAnimation: permite modificar el valor alpha de un objeto y cambiar su opacidad.
  • RotateAnimation: permite rotar un objeto.
  • ScaleAnimation: permite alterar el tamaño de un objeto.
  • TranslateAnimation: permite modificar la posición de un objeto.

 

Para utilizarlo, tan sólo tenemos que definir una animación en un fichero XML en la carpeta res>anim y aplicarlo a alguna vista. Si lo preferimos, podemos crear un objeto programáticamente en vez de con el XML.

Algunas de las propiedades que podemos definir son las siguientes:

  • duration: el tiempo que dura la animación en milisegundos.
  • fillAfter: si es true, los cambios de la animación permanecerán cuando termine, si no el objeto volverá a su estado inicial.
  • fillBefore y fillEnabled: si fillEnabled es false o si fillEnabled y fillBefore son true se aplican los cambios de la animación antes de iniciarse.
  • interpolator: los interpolators controlan la velocidad y la aceleración de los cambios de la animación.
  • repeatCount: cuántas veces se repite la animación.
  • repeatMode: define el comportamiento de la animación.
  • startOffset: retraso antes de iniciar la animación en milisegundos.

 

Además, podemos establecer un AnimationListener para controlar qué sucede cuando la animación se inicia, se repite y termina.

3.1. Ejemplo de Animation

Como ejemplo, vamos a animar esta pelota moviéndola desde la izquierda de la pantalla a la derecha.

pelota
Icono creado por Freepik de www.flaticon.com con licencia CC 3.0 BY

La imagen original es una imagen vectorial que hemos transformado para ser usado en Android. Para poder usarlo, crea un nuevo drawable resource file y pega el código que viene a continuación.

Creación de un drawable resource file

ball.xml

Como vamos a usar un vector, también tenemos que añadir un atributo en la configuración por defecto de android. Para ello modificamos el fichero de configuración de gradle añadiendo la fila destacada en el código y sincronizamos el proyecto.

Localización de build.gradle

A continuación vamos a añadir un ImageDrawable con el vector en el activity_main.xml que podemos encontrar dentro de res>layout.

Una vez ya tenemos la imagen, vamos a definir la animación. Para ello, crearemos un directorio de recursos en res llamado anim. Después añadiremos un fichero de animación en el que pegaremos el código que tenemos a continuación.

Creación de un directorio de recursos Android
Creación de un fichero XML de animación

move_right.xml

El código definido indica que se moverá horizontalmente desde la posición 0% de la anchura del contenedor hasta la 80%. Además la animación dura 2000 milisegundos y el linear_interpolator indica que la velocidad será constante.

Lo siguiente es aplicar la animación al ImageView. Para ello, vamos a modificar el MainActivity para que el método onCreate quede como el siguiente:

Hemos añadido un listener al ImageView para que cuando lo pulsemos cree la animación y la ejecute. Si lanzamos la aplicación y presionamos la pelota, veremos la animación.

3.2. Mirando más de cerca

Si debuggeamos la aplicación para ver dónde está la imagen antes y después de la animación, podremos ver cómo sus coordenadas no varían. Esto lo podemos hacer añadiendo un AnimationListener y mirando en los métodos onAnimationStart y onAnimationEnd.

Este comportamiento es debido a que la clase Animation sólo cambia la representación gráfica de los objetos y no sus propiedades reales. En un principio puede resultar banal, pero en la práctica esto puede llevar a problemas. Por ello es posible que sea necesario tener que actualizar manualmente las propiedades del objeto animado.

3.3. AnimationSet

Animation proporciona una clase llamada AnimationSet. Su finalidad es agrupar varias animaciones para ejecutarlas juntas. Además de simplificar el código también combina las transformaciones en una sola, por lo que es más eficiente. Por otro lado, hay que tener en cuenta que si definimos algunas propiedades pueden sobrescribir las de los hijos, como su duración o el modo de repetición.

Como ejemplo, vamos a modificar la animación anterior para darle un poco de efecto al movimiento de la pelota. Edita el fichero move_right.xml y sustituye el contenido por éste:

Si iniciamos la animación, veremos cómo la pelota ahora hace un giro, ya que estaremos ejecutando las dos animaciones a la vez.

4. El paquete Animator

A partir del API 11 (Android 3.0) contamos con el paquete Animator, que soluciona varias de las limitaciones de Animation. Con este tipo de animaciones modificamos tanto la representación como las propiedades del objeto.

Vamos a describir dos clases que heredan de Animator: ValueAnimator y ObjectAnimator. Algunas de las propiedades que podemos definir para ellas son las siguientes:

  • duration: duración de la animación en milisegundos.
  • interpolator: objeto que controla la velocidad y la aceleración de la animación. Se pueden usar los interpolators de Animations.
  • repeatCount: veces que se repite la animación. Se puede indicar que es infinito (constante definida en ValueAnimator).
  • frameDelay: la frecuencia teórica con la que se actualizan los frames , por defecto 10 milisegundos. El valor es teórico, ya que depende de la potencia del dispositivo. Ten en cuenta que una frecuencia menor requiere mayor número de cálculos por unidad de tiempo.

 

Al igual que con las animaciones, podemos definir un listener. En este caso tenemos varios tipos

  • AnimationListener: cuenta con métodos a los que se llama cuándo se inicia la animación, cuándo termina, cuándo se repite o cuándo se cancela.
  • AnimationUpdateListener: cuenta con un método al que se llama cuando se debe actualizar el valor en cuestión.
  • AnimationListenerAdapter: se trata de una interfaz que proporciona implementaciones vacías de los métodos de arriba. Así sólo es necesario implementar los que se necesiten.

4.1. ValueAnimator

Podemos usar ValueAnimator para animar un int, un float o un color dentro de un rango durante un tiempo determinado. La animación no se aplica directamente sobre ningún elemento de nuestra aplicación, por lo que tendremos que añadir un AnimatorUpdateListener para aplicarlo.

Como ejemplo, vamos a mover la pelota de izquierda a derecha de la pantalla de nuevo. Para ello, vamos a modificar el método onCreate de la clase MainActivity indicando el tiempo. Además vamos a añadir un pequeño delay y a indicar que la animación se ejecutará con un AccelerateInterpolator:

4.2. ObjectAnimator

ObjectAnimator hereda de ValueAnimator y su concepto es muy similar. Ofrece la ventaja de indicar directamente el atributo del objeto que se va a animar sin necesidad de establecer un listener.

Los atributos de las vistas que se pueden animar son los siguientes:

  • translationX, translationY: indican dónde está la vista como una delta desde sus coordenadas izquierda y superior.
  • rotation, rotationX, rotationY: rotación 2D y 3D
  • scaleX, scaleY: escala 2D.
  • pivotX, pitotY: definen el pivote sobre el que la rotación y la escala se calcula. Por defecto está en el centro de la vista.
  • x, y: localización de la vista como suma de su valor traslationX o traslationY y sus coordenadas izquierda o superior.
  • alpha: define la transparencia de la vista en un rango desde 0 (invisible) hasta 1 (opaco).

 

Como ejemplo, vamos a repetir el ejemplo de ValueAnimator utilizando ObjectAnimator:

Cuando vayamos a modificar varias propiedades de un objeto, podemos utilizar varios ObjectAnimator como hemos descrito arriba o utilizarlo con el método ofPropertyValuesHolder. Este método devuelve un objeto de tipo ObjectAnimator, tal y como sucedía antes, pero permite definir varias modificaciones que se darán a la vez.

A continuación, además de mover la pelota, vamos a hacer que su tamaño se duplique tanto horizontal como verticalmente:

4.3. AnimatorSet

Al igual que Animation, el paquete Animator también permite definir un set de animaciones. Sin embargo, a diferencia que Animation, también permite definir si se ejecutarán a la vez o secuencialmente.

Como ejemplo, vamos a añadir una segunda pelota y vamos a hacer que cuando se pulse una de ellas las dos se muevan a la vez. Además la inferior se moverá tras un pequeño delay.

Para empezar, modificaremos activity_main.xml para tener las dos pelotas:

Para terminar modificamos la clase MainActivity:

5. ViewPropertyAnimator

Si tenemos que modificar más de dos propiedades de un objeto es recomendable usar ViewPropertyAnimator. Cuando hay varias animaciones simultáneas, esta clase las combina para mejorar el rendimiento.

Como ejemplo, vamos a animar la pelota superior para que desaparezca, se redimensione al doble de su tamaño y, además, gire sobre sí misma. Nuevamente modificamos el método onCreate de la clase MainActivity:

Como se puede apreciar, el código se reduce, pudiendo indicar todas las animaciones a realizar en una única línea de código.

6. Movimientos con Physics

Para realizar animaciones que utilicen movimientos más naturales o que apliquen las leyes del mundo real utilizamos movimientos con físicas. A diferencia del resto de animaciones, las basadas en physics no muestran un cambio brusco al modificar la animación. Esto se debe a que el cambio se aplica como una fuerza sobre la velocidad actual, provocando una transición suave.

Android proporciona dos tipos de animaciones: SpringAnimation y FlingAnimation. La primera pretende simular una fuerza similar a la de un muelle y la segunda simula la fuerza de fricción (como cuando hacemos scroll y la animación va perdiendo velocidad).

7. Layouts y Actividades

Aunque en este tutorial no nos centraremos en ellas, android permite animar la transición entre layouts y entre actividades. Éstas se encuentran disponibles a partir del API 19 (Android 4.4) y permiten especificar el tipo de transición que se quiere, tanto para cambiar toda la interfaz como sólo alguna vista.

Además, a partir del API 21 (Android 5.0), contamos con transiciones entre actividades, es decir, entre dos layouts que pertenezcan a actividades diferentes.

8. Animar Drawables

Para animar un gráfico bitmap, podemos usar dos tipos de animación: AnimationDrawable y AnimatedVectorDrawable.

8.1. AnimationDrawable

AnimationDrawable se basa en la sucesión de varios drawables, funcionando de forma similar a un gif. Dependiendo del número de drawables que definamos y su duración se puede conseguir una transición más suave o más brusca. En XML aplicamos esta técnica con la etiqueta animation-list que funciona como un drawable.

Como ejemplo simple vamos a definir una lista de dos drawables que se alternen: un círculo y un cuadrado. Para empezar creamos tres nuevos drawables en res>drawable: las dos shapes y la animation-list.

circle.xml

square.xml

animated_shape.xml

Como podemos ver, hemos añadido el círculo y el cuadrado a la lista con una duración de 200 milisegundos cada uno. Además, hemos definido oneshot como false para que la animación no se detenga.

Pero aún nos queda añadir la animación a la aplicación, por lo que vamos a modificar el layout activity_main.xml:

Por último, volvemos a editar la clase MainActivity para crear un onClickListener que inicie la animación:

8.2. AnimatedVectorDrawable

El otro tipo de animación es AnimatedVectorDrawable, el cual permite modificar los atributos de un vector definido como una animación. Además contamos con AnimatedVectorDrawableCompat, la cual se usa para compatibilidad con versiones anteriores.

Normalmente se usan estas clases definiendo dos archivos XML. En uno se define la animación a realizar y contendrá la etiqueta object-animator. El otro contiene la etiqueta animated-vector y es donde uniremos la animación con uno de los elementos del vector. Estos elementos pueden ser tanto un group como un path, ambos con la etiqueta name definida.

A continuación vamos a animar este icono para que el color del círculo que lo rodea cambie.

icono de cerrar
Icono creado por Freepik de www.flaticon.com con licencia CC 3.0 BY

Primeramente vamos a crear un drawable siguiendo con el mismo procedimiento con el que creamos la pelota y pegaremos este código.

close_icon.xml

A continuación vamos con el objectAnimator. Para ello tenemos que crear una carpeta llamada animator dentro de res siguiendo el mismo procedimiento que cuando creamos la carpeta anim. Después, añade un nuevo fichero de animación en ella y pega este código:

black_to_white.xml

Lo siguiente es añadir un animated-vector, que será un drawable dentro de la carpeta res>drawable. En esta etiqueta tenemos que definir el atributo drawable que indica cuál es el vector a animar. Por otro lado, en target también hay que definir dos atributos: animation para la animación que hemos definido y name para el group o path sobre el que se va a aplicar.

animated_close_icon.xml

Ya tenemos el vector animado, pero aún nos queda añadirlo al layout activity_main.xml y editar la clase MainActivity para iniciar la animación.

activity_main.xml

MainActivity

Y hasta aquí este tutorial. Si quieres más información puedes acceder a los enlaces que tienes en referencias.

¡Muchas gracias por haber leído hasta aquí!

9. Referencias

https://developer.android.com/training/animation/overview
https://developer.android.com/guide/topics/graphics/view-animation
https://developer.android.com/guide/topics/graphics/prop-animation
https://developer.android.com/reference/android/animation/Animator
https://developer.android.com/reference/android/view/animation/Animation
https://developer.android.com/reference/android/view/ViewPropertyAnimator
https://developer.android.com/guide/topics/graphics/drawable-animation
https://developer.android.com/reference/android/support/graphics/drawable/AnimatedVectorDrawableCompat

1 Comentario

Dejar respuesta

Please enter your comment!
Please enter your name here