Animar gráficos drawable

Testar o Compose
O Jetpack Compose é o kit de ferramentas de interface recomendado para Android. Aprenda a usar animações no Compose.
Figura 1. Um drawable animado.

Em algumas situações, as imagens precisam ser animadas. Isso é útil se você quiser mostrar uma animação de carregamento personalizada composta por várias imagens ou se quiser que um ícone se transforme após uma ação do usuário. O Android oferece duas opções para animar drawables.

A primeira opção é usar um AnimationDrawable. Isso permite especificar vários arquivos drawable estáticos que são exibidos um por vez para criar uma animação. A segunda opção é usar um AnimatedVectorDrawable, que permite animar as propriedades de um drawable vetorial.

Usar AnimationDrawable

Uma forma de criar uma animação é carregar uma sequência de recursos drawable, como um rolo de filme. A classe AnimationDrawable é a base para esses tipos de animações drawable.

É possível definir os frames de uma animação no código usando a API da classe AnimationDrawable, mas é mais fácil defini-los com um único arquivo XML que lista os frames que compõem a animação. O arquivo XML desse tipo de animação pertence ao diretório res/drawable/ do projeto Android. Nesse caso, as instruções fornecem a ordem e a duração de cada frame na animação.

O arquivo XML consiste em um elemento <animation-list> como o nó raiz e uma série de nós <item> filhos que definem individualmente um frame, um recurso drawable e a duração dele. Confira um exemplo de arquivo XML para uma animação 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 animação é executada por três frames. Definir o atributo android:oneshot da lista como true faz com que ela ciclose uma vez e, em seguida, pare e segure no último frame. Se você definir android:oneshot como false, a animação será executada em loop.

Se você salvar esse XML como rocket_thrust.xml no diretório res/drawable/ do projeto, poderá adicioná-lo como imagem de plano de fundo a um View e chamar start() para que ele seja reproduzido. Confira um exemplo de atividade em que a animação é adicionada a uma ImageView e animada quando a tela é tocada:

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

É importante observar que o método start() chamado no AnimationDrawable não pode ser chamado durante o método onCreate() do Activity, porque o AnimationDrawable ainda não está totalmente anexado à janela. Para exibir a animação imediatamente, sem exigir interação, chame-a do método onStart() no Activity, que é chamado quando o Android torna a visualização visível na tela.

Para mais informações sobre a sintaxe XML e as tags e os atributos disponíveis, consulte Recursos de animação.

Usar AnimatedVectorDrawable

Um drawable vetorial é um tipo de drawable que pode ser escalonado sem ficar pixelado ou desfocado. A classe AnimatedVectorDrawable (e AnimatedVectorDrawableCompat para compatibilidade com versões anteriores) permite animar as propriedades de um drawable vetorial, como girá-lo ou mudar os dados do caminho para transformá-lo em uma imagem diferente.

Você normalmente define desenháveis de vetor animados em três arquivos XML:

  • Um drawable vetorial com o elemento <vector> em res/drawable/.
  • Um drawable vetorial animado com o elemento <animated-vector> em res/drawable/.
  • Um ou mais animadores de objeto com o elemento <objectAnimator> em res/animator/.

Drawables vetoriais animados podem animar os atributos dos elementos <group> e <path>. O elemento <group> define um conjunto de caminhos ou subgrupos, e o elemento <path> define os caminhos a serem desenhados.

Ao definir um drawable vetorial que você quer animar, use o atributo android:name para atribuir um nome exclusivo a grupos e caminhos para se referir a eles nas definições do animador. Exemplo:

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>

A definição de drawable vetorial animado se refere a grupos e caminhos no drawable vetorial pelos respectivos nomes:

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>

As definições de animação representam objetos ObjectAnimator ou AnimatorSet. O primeiro animador neste exemplo gira o grupo desejado em 360 graus:

res/animator/rotation.xml

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

O segundo animador nesse exemplo transforma a forma do caminho do desenhável de vetor. Os caminhos precisam ser compatíveis com a transformação: eles precisam ter o mesmo número de comandos e 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>

Confira o AnimatedVectorDrawable resultante:

Figura 2. Um AnimatedVectorDrawable.

Visualização do drawable vetorial animado (AVD)

A ferramenta de drawable vetorial animado no Android Studio permite visualizar recursos drawable animados. Ela ajuda a visualizar recursos <animation-list>, <animated-vector> e <animated-selector> no Android Studio e facilita a otimização de animações personalizadas.

Usuário visualizando e reproduzindo uma animação no Android Studio
Figura 3. A ferramenta Animated Vector Drawable no Android Studio.

Para saber mais, consulte a referência da API para AnimatedVectorDrawable.