Présentation de l'animation des propriétés

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser des animations dans Compose.
<ph type="x-smartling-placeholder"></ph> animate*AsState →

Le système d'animation des propriétés est un framework robuste qui vous permet pour animer presque tout. Vous pouvez définir une animation pour modifier n'importe quelle propriété d'objet au fil du temps, qu'elle s'affiche à l'écran ou non. Une animation de propriété modifie (champ d'un objet) sur une période spécifiée. Pour animer un élément, vous devez spécifier que vous souhaitez animer, comme sa position à l'écran, sa durée pour lesquelles vous voulez l'animer et les valeurs comprises entre elles.

Le système d'animation des propriétés vous permet de définir les caractéristiques suivantes Animation:

  • Durée: vous pouvez spécifier la durée d'une animation. La durée par défaut est de 300 ms.
  • Interpolation temporelle: vous pouvez spécifier le mode de calcul des valeurs de la propriété du temps écoulé actuel de l'animation.
  • Nombre de répétitions et comportement: vous pouvez indiquer si une animation doit se répéter ou non lorsque la fin d'une durée et le nombre de répétitions de l'animation. Vous pouvez également spécifier si l'animation doit être lue en sens inverse. Activer les lectures inversées l'animation avance, puis revient en arrière de manière répétée, jusqu'à atteindre le nombre de répétitions.
  • Ensembles d'animations: vous pouvez regrouper les animations en ensembles logiques, séquentiellement ou après des retards spécifiés.
  • Délai d'actualisation des images: vous pouvez spécifier la fréquence d'actualisation des images de votre animation. La la valeur par défaut est définie sur 10 ms, mais la vitesse à laquelle votre application peut actualiser les frames est dépend en fin de compte du niveau d'occupation global du système et de la vitesse à laquelle il peut gérer le minuteur sous-jacent.

Pour voir un exemple complet d'animation de propriété, consultez la La classe ChangeColor dans CustomTransition sur GitHub.

Fonctionnement de l'animation des propriétés

Commençons par étudier le fonctionnement d'une animation à l'aide d'un exemple simple. La figure 1 représente objet hypothétique animé avec sa propriété x, qui représente son position horizontale sur un écran. La durée de l'animation est définie sur 40 ms et la distance se déplace de 40 pixels. Toutes les 10 ms (fréquence d'actualisation des frames par défaut), l'objet se déplace horizontalement de 10 pixels. Au bout de 40 ms, l'animation s'arrête et l'objet se termine à position horizontale 40. Voici un exemple d'animation avec interpolation linéaire, ce qui signifie que se déplace à une vitesse constante.

Figure 1 : Exemple d'animation linéaire

Vous pouvez également spécifier des animations pour qu'elles aient une interpolation non linéaire. La figure 2 illustre objet hypothétique qui accélère au début de l'animation et ralentit au à la fin de l'animation. L'objet se déplace toujours de 40 pixels en 40 ms, mais de manière non linéaire. Dans commence, l'animation accélère jusqu'à la moitié, puis ralentit jusqu'à la fin de l'animation. Comme le montre la figure 2, la distance parcourue au début et à la fin de l'animation est inférieure à celle du milieu.

Figure 2. Exemple d'animation non linéaire

Examinons en détail comment les composants importants du système d'animation des propriétés pour calculer des animations comme celles illustrées ci-dessus. La figure 3 illustre la façon dont les classes principales à collaborer les uns avec les autres.

Figure 3. Mode de calcul des animations

L'objet ValueAnimator assure le suivi de la durée de votre animation. comme la durée d'exécution de l'animation et la valeur actuelle de la propriété et l'animation.

ValueAnimator encapsule un élément TimeInterpolator, qui définit l'interpolation de l'animation, et un élément TypeEvaluator, qui définit le mode de calcul des valeurs de la propriété concernée. animées. Par exemple, dans la figure 2, le TimeInterpolator utilisé serait AccelerateDecelerateInterpolator et TypeEvaluator seraient IntEvaluator.

Pour lancer une animation, créez un ValueAnimator et attribuez-lui le rôle les valeurs de début et de fin de la propriété à animer, ainsi que la durée des l'animation. Lorsque vous appelez start(), l'animation commence. Pendant toute l'animation, ValueAnimator calcule une fraction écoulée entre 0 et 1, en fonction de la durée de l'animation et du temps écoulé. La la fraction écoulée représente le pourcentage de temps pendant lequel l'animation s'est terminée, 0 signifiant 0% et 1 à 100%. Par exemple, sur la figure 1, la fraction écoulée pour t = 10 ms serait de 0,25. car la durée totale est t = 40 ms.

Lorsque ValueAnimator a terminé de calculer une fraction écoulée, il appelle la fonction TimeInterpolator actuellement définie pour calculer une fraction interpolée. Une fraction interpolée mappe la fraction écoulée à une nouvelle qui prend en compte l'interpolation temporelle définie. Par exemple, dans la figure 2, Comme l'animation accélère lentement, la fraction interpolée, d'environ 0,15, est inférieure à la fraction écoulée, 0,25, à t = 10 ms. Dans la figure 1, la fraction interpolée est toujours la même que la fraction écoulée.

Lorsque la fraction interpolée est calculée, ValueAnimator appelle la TypeEvaluator appropriée pour calculer la valeur de la la propriété que vous animez, basée sur la fraction interpolée, la valeur de départ et la valeur de fin de l'animation. Par exemple, dans la figure 2, la fraction interpolée était 0,15 pour t = 10 ms .La valeur de la propriété est donc de 0, 15 × (40 - 0), soit 6.

Différences entre l'animation des propriétés et celle des vues

Le système d'animation des vues permet uniquement d'animer View des objets. Par conséquent, si vous souhaitez animer des objets non View, vous devez implémenter votre propre code. Le système d'animation des vues est également contraint par le fait qu'il expose quelques aspects d'un objet View à animer, tels que la mise à l'échelle et la rotation d'une vue, mais pas de la couleur d'arrière-plan, par exemple.

Un autre inconvénient du système d'animation des vues est qu'il ne modifiait que l'emplacement La vue a été dessinée, et non la vue elle-même. Par exemple, si vous avez animé un bouton pour déplacer sur l'écran, le bouton s'affiche correctement, mais l'emplacement réel où vous pouvez cliquer ne change pas. Vous devez donc implémenter votre propre logique pour gérer cela.

Avec le système d'animation des propriétés, ces contraintes sont complètement supprimées, et vous pouvez animer n'importe quelle propriété de tout objet (Views et non-Views) et l'objet lui-même a été modifié. Le système d'animation des propriétés est également plus robuste. À de manière générale, vous attribuez des animateurs aux propriétés que vous voulez animer, comme la couleur, position ou taille, et peut définir certains aspects de l'animation, tels que l'interpolation la synchronisation de plusieurs animateurs.

En revanche, le système d'animation des vues prend moins de temps à configurer et nécessite moins de code à écrire. Si l'animation d'affichage accomplit tout ce que vous devez faire, ou si votre code existant fonctionne comme vous le souhaitez, il n'est pas nécessaire d'utiliser le système d'animation des propriétés. Il se peut également il est judicieux d'utiliser les deux systèmes d'animation dans des situations différentes si le cas d'utilisation se présente.

Présentation de l'API

Vous trouverez la plupart des API du système d'animation des propriétés dans android.animation. Comme le système d'animation des vues définit de nombreux interpolateurs dans android.view.animation, vous pouvez utiliser ces interpolateurs dans le système d'animation des propriétés. Les tableaux suivants décrivent les principaux du système d'animation des propriétés.

La classe Animator fournit la structure de base pour créer des animations. Normalement, vous n'utilisez pas cette classe directement, car elle ne fournit qu'un minimum fonctionnalité qui doit être étendue pour prendre en charge l'animation des valeurs. Les éléments suivants : étendent Animator:

Tableau 1. Animateurs

Classe Description
ValueAnimator Principal moteur de temps pour l'animation des propriétés, qui calcule également les valeurs des valeurs doit être animée. Il intègre toutes les fonctionnalités de base qui permettent de calculer les animations et contient les détails temporels de chaque animation, ainsi que des informations sur le fait qu'une les répétitions de l'animation, les écouteurs qui reçoivent les événements de mise à jour et la possibilité de définir des à évaluer. L'animation des propriétés se fait en deux étapes: le calcul de l'animation et en définissant ces valeurs pour l'objet et la propriété animés. ValueAnimator n'effectue pas le deuxième morceau. Vous devez donc l'écouter. pour les mises à jour des valeurs calculées par les ValueAnimator et modifier les objets que vous souhaitez animer selon votre propre logique. Consultez la section sur Pour en savoir plus, consultez la page Animation avec ValueAnimator.
ObjectAnimator Une sous-classe de ValueAnimator qui vous permet de définir une cible et la propriété d'objet à animer. Cette classe met à jour la propriété en conséquence il calcule une nouvelle valeur pour l'animation. Vous souhaitez utiliser ObjectAnimator la plupart du temps, car il facilite grandement le processus d'animation des valeurs sur les objets cibles. Toutefois, vous souhaitez parfois utiliser ValueAnimator directement, car ObjectAnimator comporte quelques restrictions supplémentaires, comme la nécessité d'utiliser des d'accesseur à l'objet cible.
AnimatorSet Fournit un mécanisme pour regrouper les animations afin qu'elles s'exécutent dans les uns par rapport aux autres. Vous pouvez définir des animations à lire ensemble, séquentiellement ou après un délai spécifique. Reportez-vous à la section Choréographie de plusieurs avec Animator Sets.

Les évaluateurs indiquent au système d'animation des propriétés comment calculer les valeurs pour une propriété donnée . Ils prennent les données temporelles fournies par un Animator. de début et de fin de l'animation, puis calculer les valeurs animées de la propriété à partir de ces données. Le système d'animation des propriétés fournit les évaluateurs suivants:

Tableau 2. Évaluateurs

Classe/Interface Description
IntEvaluator Évaluateur par défaut pour calculer les valeurs des propriétés int.
FloatEvaluator Évaluateur par défaut pour calculer les valeurs des propriétés float.
ArgbEvaluator Évaluateur par défaut pour calculer les valeurs des propriétés de couleur représentées sous forme de valeurs hexadécimales.
TypeEvaluator Interface qui vous permet de créer votre propre évaluateur. Si vous animez une propriété d'objet qui n'est pas un int, un float ou une couleur, vous devez implémenter l'interface TypeEvaluator pour spécifier pour calculer les valeurs animées de la propriété d'objet. Vous pouvez également spécifier un TypeEvaluator personnalisé pour int, float et une couleur. si vous souhaitez traiter ces types différemment du comportement par défaut. Pour en savoir plus, consultez la section sur l'utilisation d'un évaluateur de type. sur la façon de rédiger un évaluateur personnalisé.

Un interpolateur de temps définit le mode de calcul des valeurs spécifiques d'une animation fonction du temps. Par exemple, vous pouvez spécifier que les animations se déroulent de façon linéaire sur l'ensemble animation, qui signifie qu'elle se déplace uniformément tout au long de la durée, ou vous pouvez spécifier des animations d'utiliser un temps non linéaire, par exemple, une accélération au début et une diminution au à la fin de l'animation. Le tableau 3 décrit les interpolateurs contenus dans android.view.animation. Si aucun des interpolateurs fournis ne convient selon vos besoins, implémentez l'interface TimeInterpolator et créez la vôtre. Pour en savoir plus sur l'écriture d'une requête personnalisée, consultez la section Utiliser des interpolateurs. un interpolateur.

Tableau 3 : Interpolateurs

Classe/Interface Description
AccelerateDecelerateInterpolator Un interpolateur dont la fréquence de changement commence et se termine lentement, mais accélère vers le milieu.
AccelerateInterpolator Un interpolateur dont la fréquence de changement démarre lentement, puis accélère.
AnticipateInterpolator Interpolateur dont le changement commence en arrière, puis avance.
AnticipateOvershootInterpolator un interpolateur dont le changement commence à l'envers, avance et dépasse. la valeur cible, puis revient finalement à la valeur finale.
BounceInterpolator Un interpolateur dont le changement rebondit à la fin.
CycleInterpolator Interpolateur dont l'animation se répète pendant un nombre spécifié de cycles.
DecelerateInterpolator Un interpolateur dont la fréquence de changement démarre rapidement, puis ralentit.
LinearInterpolator Interpolateur dont la fréquence de changement est constante.
OvershootInterpolator un interpolateur dont le changement avance et dépasse la dernière valeur, puis est renvoyée.
TimeInterpolator Interface qui vous permet d'implémenter votre propre interpolateur

Créer une animation à l'aide de ValueAnimator

La classe ValueAnimator vous permet d'animer des valeurs d'un certain type pour la durée d'une animation en spécifiant un ensemble de int, float ou une couleur ; pour l'animation. Vous obtenez un ValueAnimator en appelant l'une des ses méthodes de fabrique: ofInt(), ofFloat() ou ofObject(). Exemple :

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

Dans ce code, ValueAnimator commence à calculer les valeurs de la , comprise entre 0 et 100, pour une durée de 1 000 ms, lorsque la méthode start() est exécutée.

Vous pouvez également spécifier un type personnalisé à animer en procédant comme suit:

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

Dans ce code, ValueAnimator commence à calculer les valeurs de la d'animation, entre startPropertyValue et endPropertyValue à l'aide de la fournie par MyTypeEvaluator pendant 1 000 ms, lorsque la méthode start() s'exécute.

Vous pouvez utiliser les valeurs de l'animation en ajoutant une AnimatorUpdateListener à l'objet ValueAnimator, comme indiqué dans code suivant:

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

Java

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

Dans le onAnimationUpdate() vous pouvez accéder à la valeur d'animation mise à jour et l'utiliser dans une propriété de l'une de vos vues. Pour en savoir plus sur les écouteurs, consultez la section Écouteurs d'animation.

Créer des animations à l'aide d'ObjectAnimator

ObjectAnimator est une sous-classe de ValueAnimator (décrite dans la section précédente) et combine les codes temporels. et le calcul des valeurs de ValueAnimator, avec la possibilité de animer une propriété nommée d'un objet cible. Cela facilite grandement l'animation de n'importe quel objet, vous n'avez plus besoin d'implémenter ValueAnimator.AnimatorUpdateListener. car la propriété animée est automatiquement mise à jour.

L'instanciation d'un ObjectAnimator est semblable à ValueAnimator, mais vous devez également spécifier l'objet et le nom de sa propriété (comme une chaîne) ainsi que les valeurs à animer entre:

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

Pour que les ObjectAnimator mettent à jour les propriétés correctement, vous devez procéder comme suit:

  • La propriété d'objet que vous animez doit avoir une fonction setter (en camel case) sous la forme suivante : set<PropertyName>() Étant donné que ObjectAnimator met à jour automatiquement la propriété pendant l'animation, il doit pouvoir y accéder avec cette méthode setter. Par exemple, si le nom de la propriété est foo, vous devez disposer d'une méthode setFoo(). Si cette méthode setter n'existe pas, vous avez trois options: <ph type="x-smartling-placeholder">
      </ph>
    • Ajoutez la méthode setter à la classe si vous disposez des droits nécessaires.
    • Utilisez une classe wrapper que vous êtes autorisé à modifier et faites en sorte que ce wrapper reçoive le avec une méthode setter valide et la transmettre à l'objet d'origine.
    • Utilisez ValueAnimator à la place.
  • Si vous ne spécifiez qu'une seule valeur pour le paramètre values... dans l'une des méthodes de fabrique ObjectAnimator, elle est supposée être la valeur de fin de la de l'animation. Par conséquent, la propriété d'objet que vous animez doit avoir une fonction getter. utilisée pour obtenir la valeur de départ de l'animation. La fonction getter doit se trouver dans au format get<PropertyName>(). Par exemple, si le nom de la propriété est foo, vous devez disposer d'une méthode getFoo().
  • Les méthodes getter (si nécessaire) et setter de la propriété que vous animez doivent opèrent sur le même type que les valeurs de début et de fin que vous spécifiez dans ObjectAnimator. Par exemple, vous devez avoir targetObject.setPropName(float) et targetObject.getPropName() si vous construisez le ObjectAnimator suivant:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
    
  • Selon la propriété ou l'objet que vous animez, vous devrez peut-être appeler la méthode invalidate() sur une vue pour forcer l'écran à se redessiner avec le les valeurs animées mises à jour. Pour ce faire, utilisez onAnimationUpdate() . Par exemple, l'animation de la propriété couleur d'un objet Drawable ne provoque que des mises à jour de la à l'écran lorsque cet objet se redessine. Tous les setters de propriété sur View, tels que setAlpha() et setTranslationX() invalider la vue correctement. Vous n'avez donc pas besoin d'invalider la vue lorsque vous appelez ces avec de nouvelles valeurs. Pour en savoir plus sur les écouteurs, consultez la section Écouteurs d'animation.

Chorégraphiez plusieurs animations à l'aide d'AnimatorSet

Dans de nombreux cas, vous souhaitez lire une animation qui dépend du moment où une autre animation démarre ou se termine. Le système Android vous permet de regrouper des animations dans un AnimatorSet, afin que vous puissiez spécifier si vous souhaitez lancer des animations. simultanément, de manière séquentielle ou après un délai spécifié. Vous pouvez également imbriquer des objets AnimatorSet les uns dans les autres.

L'extrait de code suivant lit l'élément Animator suivant : des objets de la manière suivante:

  1. Lit bounceAnim.
  2. Lit squashAnim1, squashAnim2, stretchAnim1 et stretchAnim2 en même temps.
  3. Lit bounceBackAnim.
  4. Lit fadeAnim.

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

Java

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

Écouteurs d'animation

Vous pouvez écouter les événements importants pendant la durée d'une animation avec les écouteurs décrits ci-dessous.

  • Animator.AnimatorListener
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() : appelé sur chaque image de l'animation. Écouter cet événement pour utilisent les valeurs calculées générées par ValueAnimator lors d'une de l'animation. Pour utiliser cette valeur, interrogez l'objet ValueAnimator. transmis à l'événement pour obtenir la valeur animée actuelle avec la méthode getAnimatedValue(). Implémentation L'écouteur est requis si vous utilisez ValueAnimator.

      Selon la propriété ou l'objet que vous animez, vous devrez peut-être appeler invalidate() sur une vue pour forcer cette zone de la l'écran pour se redessiner avec les nouvelles valeurs animées. Par exemple, l'animation propriété color d'un objet drawable ne provoque des mises à jour de l'écran que lorsque cet objet se redessine automatiquement. Tous les setters de propriété sur View, tels que setAlpha() et setTranslationX() invalider la vue correctement, vous n'avez donc pas besoin d'invalider la vue lorsque vous appelez ces méthodes avec de nouvelles valeurs.

Vous pouvez étendre la classe AnimatorListenerAdapter au lieu de implémenter l'interface Animator.AnimatorListener, vous souhaitez implémenter toutes les méthodes de Animator.AnimatorListener. de commande. La classe AnimatorListenerAdapter fournit une valeur des méthodes que vous pouvez choisir de remplacer.

Par exemple, l'extrait de code suivant crée un AnimatorListenerAdapter pour onAnimationEnd() uniquement rappel:

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

Java

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

Animer les modifications de mise en page dans les objets ViewGroup

Le système d'animation des propriétés permet d'animer les modifications apportées aux objets ViewGroup. et permettent d'animer facilement les objets View eux-mêmes.

Vous pouvez animer les modifications de mise en page dans un ViewGroup avec la LayoutTransition. Les vues d'un ViewGroup les animations apparaissent et disparaissent lorsque vous les ajoutez à les supprimer d'un ViewGroup ou lorsque vous appelez la méthode Méthode setVisibility() avec VISIBLE, INVISIBLE ou GONE Les vues restantes dans le ViewGroup s'animent à leur nouvelle position lorsque vous ajoutez ou supprimez des vues. Vous pouvez définir les animations suivantes dans un objet LayoutTransition ; en appelant setAnimator() et en transmettant un objet Animator avec l'une des Constantes LayoutTransition suivantes:

  • APPEARING : indicateur indiquant l'animation exécutée sur les éléments qui apparaissent dans le conteneur.
  • CHANGE_APPEARING : indicateur indiquant l'animation exécutée sur les éléments en raison de l'apparition d'un nouvel élément dans le conteneur.
  • DISAPPEARING : indicateur indiquant l'animation exécutée sur les éléments disparaissent du conteneur.
  • CHANGE_DISAPPEARING : indicateur indiquant l'animation exécutée sur les éléments qui changent lorsqu'un élément disparaît du conteneur.

Vous pouvez définir vos propres animations personnalisées pour ces quatre types d'événements afin de personnaliser l'apparence des transitions de mise en page, ou demandez simplement au système d'animation d'utiliser les animations par défaut.

Pour définir l'attribut android:animateLayoutchanges sur true pour la ViewGroup effectuent les opérations suivantes:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

Lorsque cet attribut est défini sur "true", les vues ajoutées ou supprimées de la ViewGroup et les vues restantes dans le ViewGroup.

Animer les changements d'état d'une vue à l'aide de StateListAnimator

La classe StateListAnimator vous permet de définir des animateurs qui s'exécutent lorsque l'état d'une vue change. Cet objet se comporte comme un wrapper pour Animator, qui appelle cette animation chaque fois que la valeur l'état de la vue (par exemple, "appui" ou "sélectionné").

Le StateListAnimator peut être défini dans une ressource XML avec une racine Élément <selector> et éléments <item> enfants spécifiés chacun un état de vue différent défini par la classe StateListAnimator. Chaque <item> contient la définition d'un ensemble d'animation de propriété.

Par exemple, le fichier suivant crée un animateur de liste d'états qui modifie les échelles x et y de la vue lorsque l'utilisateur appuie dessus:

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

Pour associer l'animateur de liste d'états à une vue, ajoutez le android:stateListAnimator comme suit:

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

Les animations définies dans animate_scale.xml sont maintenant utilisées lorsque l'objet les changements d'état.

Pour attribuer un animateur de liste d'états à une vue de votre code, utilisez la méthode AnimatorInflater.loadStateListAnimator(), puis attribuez l'animateur au votre vue avec la méthode View.setStateListAnimator().

Au lieu d'animer les propriétés de la vue, vous pouvez lancer une animation drawable entre les changements d'état à l'aide de AnimatedStateListDrawable. Certains des widgets système dans Android 5.0 utilise ces animations par défaut. L'exemple suivant montre comment pour définir un AnimatedStateListDrawable en tant que ressource XML:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

Utiliser un TypeEvaluator

Si vous souhaitez animer un type inconnu du système Android, vous pouvez créer le vôtre en implémentant l'interface TypeEvaluator. Les types qui sont connus par le système Android sont int, float ou une couleur, qui sont compatible avec les types IntEvaluator, FloatEvaluator et ArgbEvaluator évaluateurs.

Il n'y a qu'une seule méthode à implémenter dans TypeEvaluator de l'interface, la méthode evaluate(). Cela permet l'animation que vous utilisez pour renvoyer une valeur appropriée pour votre propriété animée au niveau point actuel de l'animation. La classe FloatEvaluator illustre procédez comme suit:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

Java

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

Remarque:Lorsque ValueAnimator (ou ObjectAnimator) s'exécute, il calcule une fraction actuelle du temps écoulé (une valeur comprise entre 0 et 1), puis calcule une version interpolée de cette valeur en fonction en fonction de l'interpolateur que vous utilisez. La fraction interpolée est ce que votre TypeEvaluator reçoit via le paramètre fraction. Vous devez donc sans tenir compte de l'interpolateur lors du calcul des valeurs animées.

Utiliser des interpolateurs

Un interpolateur définit le mode de calcul des valeurs spécifiques d'une animation en tant que fonction de en temps réel. Par exemple, vous pouvez spécifier que les animations doivent se dérouler de façon linéaire tout au long de l'animation, c'est-à-dire que l'animation se déplace uniformément tout au long de la vidéo, ou vous pouvez spécifier des animations à utiliser une durée non linéaire (par exemple, en utilisant l'accélération ou la décélération au début ou à la fin de la de l'animation.

Les interpolateurs du système d'animation reçoivent une fraction des animateurs représentant la le temps écoulé de l'animation. Les interpolateurs modifient cette fraction pour qu'elle coïncide avec le type de l'animation qu'il vise à fournir. Le système Android fournit un ensemble d'interpolateurs courants le android.view.animation package. Si aucune de ces options ne convient vous pouvez implémenter l'interface TimeInterpolator et créer votre vous-même.

À titre d'exemple, la comparaison ci-dessous montre comment l'interpolateur par défaut AccelerateDecelerateInterpolator et le LinearInterpolator calculent les fractions interpolées. LinearInterpolator n'a aucun effet sur la fraction écoulée. AccelerateDecelerateInterpolator accélère dans l'animation et ralentit. Les méthodes suivantes définissent la logique de ces interpolateurs:

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

Java

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

Java

@Override
public float getInterpolation(float input) {
    return input;
}

Le tableau suivant représente les valeurs approximatives calculées par ces pour une animation de 1 000 ms:

ms écoulés Fraction écoulée/Fraction interpolée (linéaire) Fraction interpolée (Accélérer/Décrémenter)
0 0 0
200 0,2 0,1
400 0,4 0,345
600 0,6 0,8
800 0,8 0,9
1000 1 1

Comme le montre le tableau, LinearInterpolator modifie les valeurs à la même vitesse, soit 0,2 par tranche de 200 ms. AccelerateDecelerateInterpolator modifie les valeurs entre 200 ms et 600 ms plus rapidement que LinearInterpolator, et entre 600 ms et 600 ms 1000ms.

Spécifier des images clés

Un objet Keyframe est constitué d'une paire heure/valeur qui vous permet de définir un état spécifique à un moment précis d'une animation. Chaque image clé peut aussi avoir sa propre pour contrôler le comportement de l'animation dans l'intervalle entre et celle de l'image clé.

Pour instancier un objet Keyframe, vous devez utiliser l'une des méthodes de fabrique méthodes, ofInt(), ofFloat() ou ofObject() pour obtenir le type approprié de Keyframe. Vous appelez ensuite la méthode de fabrique ofKeyframe() pour obtenir un objet PropertyValuesHolder. Une fois l'objet récupéré, obtenir un animateur en transmettant l'objet PropertyValuesHolder et objet à animer. L'extrait de code suivant montre comment procéder:

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

Java

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

Animer des vues

Le système d'animation des propriétés permet une animation simplifiée des objets et des offres View. quelques avantages par rapport au système d'animation des vues. Vue d'animation a transformé les objets View en modifiant la façon dont ils étaient dessinés. C'était gérées dans le conteneur de chaque vue, car la vue elle-même n'avait aucune propriété à manipuler. La vue était alors animée, mais l'objet View lui-même n'a pas été modifié. Ce a entraîné un comportement, par exemple un objet qui existait encore à son emplacement d'origine, alors qu'il était dessinées sur un autre emplacement sur l'écran. Dans Android 3.0, les nouvelles propriétés et les attributs des méthodes getter et setter ont été ajoutées pour éliminer cet inconvénient.

Le système d'animation des propriétés pouvez animer les vues à l'écran en modifiant les propriétés réelles des objets View. Dans De plus, les vues appellent automatiquement la méthode invalidate(). pour actualiser l'écran chaque fois que ses propriétés sont modifiées. Voici les nouvelles propriétés de la classe View qui facilitent les animations de propriétés:

  • translationX et translationY: ces propriétés contrôlent l'emplacement La vue se situe sous la forme d'un delta par rapport à ses coordonnées gauche et supérieure, qui sont définies par sa mise en page conteneur.
  • rotation, rotationX et rotationY: ces propriétés contrôler la rotation en 2D (propriété rotation) et en 3D autour du point pivot.
  • scaleX et scaleY: ces propriétés contrôlent la mise à l'échelle 2D d'un Vue autour du point pivot
  • pivotX et pivotY: ces propriétés contrôlent l'emplacement point pivot autour duquel se produisent les transformations de rotation et de mise à l'échelle. Par défaut, le tableau croisé dynamique est située au centre de l'objet.
  • x et y: il s'agit de propriétés utilitaires simples permettant de décrire emplacement final de la vue dans son conteneur, en additionnant les valeurs gauche et supérieure et translationX et translationY.
  • alpha: représente la transparence alpha sur la vue. Cette valeur est 1 (opaque) par défaut, la valeur 0 représentant une transparence totale (non visible).

Pour animer une propriété d'un objet View, comme sa couleur ou sa valeur de rotation, il vous suffit de créer un outil d'animation de propriété et spécifier la propriété View à et l'animation. Exemple :

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

Java

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

Pour en savoir plus sur la création d'animateurs, consultez les sections sur l'animation avec ValueAnimator et ObjectAnimator.

Créer une animation à l'aide de ViewPropertyAnimator

ViewPropertyAnimator permet d'animer facilement plusieurs les propriétés d'un View en parallèle, à l'aide d'un seul Animator sous-jacent . Il se comporte comme un ObjectAnimator, car il modifie le valeurs réelles des propriétés de la vue, mais cette méthode est plus efficace pour animer de nombreuses propriétés une seule fois. De plus, le code d'utilisation de ViewPropertyAnimator est très plus concis et plus facile à lire. Les extraits de code suivants montrent les différences d'utilisation de plusieurs ObjectAnimator objets, un seul ObjectAnimator, et le ViewPropertyAnimator quand pour animer simultanément les propriétés x et y d'une vue.

Plusieurs objets ObjectAnimator

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

Java

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

One ObjectAnimator

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

Java

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

Java

myView.animate().x(50f).y(100f);

Pour en savoir plus sur ViewPropertyAnimator, consultez les développeurs Android correspondants blog post.

Déclarer des animations en XML

Le système d'animation des propriétés vous permet de déclarer des animations de propriétés avec XML au lieu de faire de manière programmatique. En définissant vos animations en XML, vous pouvez facilement les réutiliser dans plusieurs activités et modifier plus facilement la séquence d'animation.

Pour distinguer les fichiers d'animation qui utilisent les nouvelles API Animation de propriétés de ceux qui utilisent la ancien framework d'animation des vues, À partir d'Android 3.1, vous devez enregistrer les fichiers XML pour les animations de propriétés dans le répertoire res/animator/.

Les classes d'animation de propriété suivantes acceptent la déclaration XML avec la propriété les balises XML suivantes:

Pour trouver les attributs que vous pouvez utiliser dans votre déclaration XML, consultez la section Animation ressources. L'exemple suivant lit les deux ensembles d'animations d'objets de manière séquentielle, le premier ensemble imbriqué lisant deux animations d'objets ensemble:

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

Pour exécuter cette animation, vous devez gonfler les ressources XML dans le code en un objet AnimatorSet, puis définir les objets cibles de toutes les animations avant de démarrer l'ensemble d'animation. Pour simplifier les choses, l'appel de setTarget() spécifie un objet cible unique pour tous les enfants de AnimatorSet. Pour ce faire, entrez le code suivant :

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

Java

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

Vous pouvez également déclarer un ValueAnimator en XML, comme illustré dans l'exemple suivant:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

Pour utiliser l'ValueAnimator précédent dans votre code : doit gonfler l'objet, ajouter une AnimatorUpdateListener, obtenir la valeur d'animation mise à jour et l'utiliser dans une propriété de l'une de vos vues ; comme indiqué dans le code suivant:

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

Java

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

Pour plus d'informations sur la syntaxe XML permettant de définir des animations de propriétés, consultez la section Animation ressources .

Effets potentiels sur les performances de l'interface utilisateur

Les animateurs qui mettent à jour l'interface utilisateur entraînent un rendu supplémentaire pour chaque image dans l'exécution de l'animation. C'est pourquoi l'utilisation d'animations gourmandes en ressources peut avoir un impact négatif sur les performances de votre application.

La tâche requise pour animer votre interface utilisateur est ajoutée à l'étape d'animation de le pipeline de rendu. Vous pouvez savoir si vos animations ont un impact sur le les performances de votre application en activant l'option Rendu GPU du profil, en surveillant l'étape de l'animation. Pour en savoir plus, consultez la section Rendu GPU du profil tutoriel.