Cómo animar gráficos con elementos de diseño

Prueba el estilo de Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Aprende a usar animaciones en Compose.
Figura 1: Un elemento de diseño animado.

En algunas situaciones, las imágenes deben ser animadas. Esto resulta útil si quieres mostrar una animación de carga personalizada compuesta por varias imágenes o si quieres que un ícono se transforme después de la acción de un usuario. Android ofrece dos opciones para animar elementos de diseño.

La primera opción es usar un AnimationDrawable. Esto te permite especificar varios archivos de elementos de diseño estáticos que se muestran uno a la vez para crear una animación. La segunda opción es usar un objeto AnimatedVectorDrawable, que te permite animar las propiedades de un elemento de diseño vectorial.

Cómo usar AnimationDrawable

Una forma de crear una animación es cargar una secuencia de recursos de elementos de diseño, como un rollo de película. La clase AnimationDrawable es la base para este tipo de animaciones de elementos de diseño.

Puedes definir los fotogramas de una animación en tu código si usas la API de la clase AnimationDrawable, pero es más fácil definirlos con un solo archivo en formato XML que enumere los fotogramas que conforman la animación. El archivo en formato XML para este tipo de animación debe encontrarse en el directorio res/drawable/ de tu proyecto de Android. En este caso, las instrucciones indican el orden y la duración de cada fotograma de la animación.

El archivo en formato XML consta de un elemento <animation-list> como nodo raíz y una serie de nodos secundarios <item>, cada uno de los cuales define un fotograma (un recurso de elemento de diseño y su duración). El siguiente es un archivo en formato XML de ejemplo para una animación Drawable:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

Esta animación se ejecuta durante tres fotogramas. Si se establece el atributo android:oneshot de la lista en true, se hace un ciclo una vez y, luego, se detiene y se mantiene presionado el último fotograma. Si configuras android:oneshot como false, la animación se repite.

Si guardas este XML como rocket_thrust.xml en el directorio res/drawable/ del proyecto, puedes agregarlo como imagen de fondo a un View y, luego, llamar a start() para que se reproduzca. Este es un ejemplo de una actividad en la que la animación se agrega a un ImageView y, luego, se anima cuando se toca la pantalla:

Kotlin

private lateinit var rocketAnimation: AnimationDrawable

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val rocketImage = findViewById<ImageView>(R.id.rocket_image).apply {
        setBackgroundResource(R.drawable.rocket_thrust)
        rocketAnimation = background as AnimationDrawable
    }

    rocketImage.setOnClickListener({ rocketAnimation.start() })
}

Java

AnimationDrawable rocketAnimation;

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

  rocketImage.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        rocketAnimation.start();
      }
  });
}

Es importante tener en cuenta que no se puede llamar al método start() al que se llama en AnimationDrawable durante el método onCreate() de tu Activity porque AnimationDrawable aún no está completamente conectado a la ventana. Para reproducir la animación de inmediato, sin requerir interacción, puedes llamarla desde el método onStart() en tu Activity, al que se llama cuando Android hace que la vista sea visible en la pantalla.

Para obtener más información sobre la sintaxis XML y las etiquetas y los atributos disponibles, consulta Recursos de animación.

Cómo usar AnimatedVectorDrawable

Un elemento de diseño vectorial es un tipo de elemento de diseño que se puede escalar sin verse pixelado ni borroso. La clase AnimatedVectorDrawable (y AnimatedVectorDrawableCompat para retrocompatibilidad) te permite animar las propiedades de un elemento de diseño vectorial, como rotarlo o cambiar los datos de la ruta para transformarlo en una imagen diferente.

Generalmente, las interfaces animadas dibujables en vector se definen en tres archivos XML:

  • Un elemento de diseño vectorial con el elemento <vector> en res/drawable/.
  • Un elemento de diseño vectorial animado con el elemento <animated-vector> en res/drawable/.
  • Uno o más animadores de objetos con el elemento <objectAnimator> en res/animator/

Los elementos de diseño vectoriales animados pueden animar los atributos de los elementos <group> y <path>. El elemento <group> define un conjunto de rutas de acceso o subgrupos, y el elemento <path> define rutas para dibujar.

Cuando definas un elemento de diseño vectorial que quieras animar, usa el atributo android:name para asignar un nombre único a grupos y rutas de acceso, de modo que puedas hacer referencia a ellos desde las definiciones del animador. Por ejemplo:

res/drawable/vectordrawable.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

La definición del elemento de diseño vectorial animado hace referencia a los grupos y las rutas de acceso del elemento de diseño vectorial por sus nombres:

res/drawable/animatorvectordrawable.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation" />
    <target
        android:name="v"
        android:animation="@animator/path_morph" />
</animated-vector>

Las definiciones de animación representan objetos ObjectAnimator o AnimatorSet. El primer animador de este ejemplo rota el grupo de destino 360 grados:

res/animator/rotation.xml

<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

El segundo animador de este ejemplo transforma la ruta del elemento de diseño vectorial de una forma a otra. Las rutas de acceso deben ser compatibles para la transformación: deben tener la misma cantidad de comandos y de parámetros para cada comando.

res/animator/path_morph.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>

Este es el AnimatedVectorDrawable resultante:

Figura 2: Un objeto AnimatedVectorDrawable.

Vista previa de elementos de diseño vectorial animado (AVD)

La herramienta Elemento de diseño vectorial animado de Android Studio te permite obtener una vista previa de los recursos de elementos de diseño animados. Esta herramienta te permite obtener una vista previa de los recursos <animation-list>, <animated-vector> y <animated-selector> en Android Studio, y facilita la definición de tus animaciones personalizadas.

Un usuario obtiene una vista previa de una animación y la reproduce en Android Studio
Figura 3: La herramienta Elemento de diseño vectorial animado de Android Studio

Para obtener más información, consulta la referencia de la API de AnimatedVectorDrawable.