Animer des images drawables

Essayer Compose
Jetpack Compose est le kit d'outils d'UI recommandé pour Android. Découvrez comment utiliser des animations dans Compose.
Figure 1 : Un drawable animé.

Dans certains cas, les images doivent être animées. Cela est utile si vous souhaitez afficher une animation de chargement personnalisée composée de plusieurs images ou si vous souhaitez qu'une icône se transforme après l'action d'un utilisateur. Android propose deux options pour animer des drawables.

La première consiste à utiliser un AnimationDrawable. Vous pouvez ainsi spécifier plusieurs fichiers drawable statiques qui s'affichent un à la fois pour créer une animation. La deuxième option consiste à utiliser un AnimatedVectorDrawable, qui vous permet d'animer les propriétés d'un drawable vectoriel.

Utiliser AnimationDrawable

Pour créer une animation, vous pouvez charger une séquence de ressources drawable, comme un film. La classe AnimationDrawable est la base de ces types d'animations drawable.

Vous pouvez définir les images d'une animation dans votre code à l'aide de l'API de la classe AnimationDrawable, mais il est plus facile de les définir avec un seul fichier XML qui liste les images qui constituent l'animation. Le fichier XML de ce type d'animation se trouve dans le répertoire res/drawable/ de votre projet Android. Dans ce cas, les instructions indiquent l'ordre et la durée de chaque image de l'animation.

Le fichier XML se compose d'un élément <animation-list> comme nœud racine et d'une série de nœuds <item> enfants qui définissent chacun un frame (une ressource drawable et sa durée). Voici un exemple de fichier XML pour une animation 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>

Cette animation s'exécute pendant trois frames. Si l'attribut android:oneshot de la liste est défini sur true, elle s'exécute une fois, puis s'arrête et s'arrête sur la dernière image. Si vous définissez android:oneshot sur false, l'animation est lue en boucle.

Si vous enregistrez ce fichier XML sous le nom rocket_thrust.xml dans le répertoire res/drawable/ du projet, vous pouvez l'ajouter en tant qu'image de fond à un élément View, puis appeler start() pour l'exécuter. Voici un exemple d'activité dans laquelle l'animation est ajoutée à un ImageView, puis animée lorsque l'écran est touché :

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

Il est important de noter que la méthode start() appelée sur AnimationDrawable ne peut pas être appelée pendant la méthode onCreate() de votre Activity, car AnimationDrawable n'est pas encore entièrement associé à la fenêtre. Pour lire l'animation immédiatement, sans nécessiter d'interaction, vous pouvez l'appeler à partir de la méthode onStart() dans votre Activity, qui est appelée lorsque Android rend la vue visible à l'écran.

Pour en savoir plus sur la syntaxe XML ainsi que sur les balises et les attributs disponibles, consultez la section Ressources d'animation.

Utiliser AnimatedVectorDrawable

Un drawable vectoriel est un type de drawable qui peut être mis à l'échelle sans devenir pixélisé ni flou. La classe AnimatedVectorDrawable (et AnimatedVectorDrawableCompat pour la rétrocompatibilité) vous permet d'animer les propriétés d'un drawable vectoriel, comme le faire pivoter ou modifier les données du chemin pour le transformer en une autre image.

Vous définissez généralement des drawables vectoriels animés dans trois fichiers XML :

  • Un drawable vectoriel avec l'élément <vector> dans res/drawable/.
  • Un drawable vectoriel animé avec l'élément <animated-vector> dans res/drawable/.
  • Un ou plusieurs animateurs d'objets avec l'élément <objectAnimator> dans res/animator/.

Les drawables vectoriels animés peuvent animer les attributs des éléments <group> et <path>. L'élément <group> définit un ensemble de chemins ou de sous-groupes, tandis que l'élément <path> définit les chemins à tracer.

Lorsque vous définissez un élément vectoriel drawable que vous souhaitez animer, utilisez l'attribut android:name pour attribuer un nom unique aux groupes et aux chemins, afin de pouvoir vous y référer à partir de vos définitions d'animateur. Exemple :

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 définition du drawable vectoriel animé fait référence aux groupes et aux chemins qu'il contient par leur nom:

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>

Les définitions de l'animation représentent des objets ObjectAnimator ou AnimatorSet. Le premier animateur de cet exemple fait pivoter le groupe cible de 360 degrés :

res/animator/rotation.xml

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

Dans cet exemple, le deuxième outil d'animation transforme le tracé du drawable vectoriel d'une forme à une autre. Les chemins d'accès doivent être compatibles avec le morphologie: ils doivent comporter le même nombre de commandes et le même nombre de paramètres pour chaque commande.

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>

Voici le AnimatedVectorDrawable obtenu:

Figure 2. Un AnimatedVectorDrawable.

Aperçu du drawable vectoriel animé (AVD)

L'outil Drawable vectoriel animé dans Android Studio vous permet de prévisualiser les ressources drawable animées. Cet outil vous permet de prévisualiser les ressources <animation-list>, <animated-vector> et <animated-selector> dans Android Studio et d'affiner plus facilement vos animations personnalisées.

Utilisateur prévisualisant et lisant une animation dans Android Studio
Figure 3 : Outil Drawable vectoriel animé dans Android Studio.

Pour en savoir plus, consultez la documentation de référence de l'API pour AnimatedVectorDrawable.