À propos de l'utilisation et du résumé de l'animation d'image Android, de l'animation d'interpolation et de l'animation d'attributs. (Code source ci-joint)

Remarque : Le contenu est important, vous pouvez donc le lire en morceaux. Il peut être divisé en trois conférences plus tard.

1. Résumé de l'animation Android

1. Animation d'image

L'animation d'image simule en fait les effets d'animation en lisant continuellement des images.

Voici deux façons d’y parvenir :

1. Méthode de fichier XML

  1. Créez d’abord animation_lufi.xml sous drawable

    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
        <item android:drawable="@drawable/image7"
            android:duration="200"/>
        <item android:drawable="@drawable/image8"
            android:duration="200"/>
        <item android:drawable="@drawable/image9"
            android:duration="200"/>
        <item android:drawable="@drawable/image10"
            android:duration="200"/>
    
    </animation-list>
    

    Vous pouvez prévisualiser l'effet :

Insérer la description de l'image ici

  1. Ajoutez animation_lufi.xml comme arrière-plan dans la vue dans le fichier de mise en page

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <View
            android:id="@+id/image"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:background="@drawable/animation_lufi"    
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/end" />
    </androidx.constraintlayout.widget.ConstraintLayout>
    
  2. Obtenez l'animation en code Java

    animationDrawable = (AnimationDrawable) img.getBackground();
    
  3. Utilisez cette animation

    animationDrawable.start(); //开启动画
    
    animationDrawable.stop(); //停止动画
    

2. Méthode de code Java

  1. En code Java :

            animationDrawable = new AnimationDrawable();
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.image7),250);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.image8),250);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.image9),250);
            animationDrawable.addFrame(getResources().getDrawable(R.drawable.image10),250);
            img.setBackground(animationDrawable);
    
    1. Les autres utilisations restent inchangées. C'est juste que la façon d'obtenir l'instance est différente de la façon d'ajouter le cadre.

2. Animation pour adolescents

Les développeurs d'animation interpolaire n'ont qu'à spécifier les « images clés » de début et de fin de l'animation, et les « images intermédiaires » des changements d'animation sont calculées et complétées par le système.

1. Types d'animations interpolaires

AlphaAnimation:: Effet dégradé de transparence, précisez la transparence de début et de fin lors de la création, ainsi que la durée de l'animation, la plage de changement de transparence (0,1), 0 est complètement transparent, 1 est complètement opaque ; label correspondant <alpha/>!
ScaleAnimation: Effet de dégradé d'échelle. Lors de la création, vous devez spécifier les rapports de mise à l'échelle de début et de fin, ainsi que le point de référence de mise à l'échelle et la durée de l'animation ; <scale/>étiquette correspondante !
TranslateAnimation: Effet de dégradé de déplacement, précisez les positions de début et de fin lors de la création, et précisez la durée de l'animation ; <translate/>étiquette correspondante !
RotateAnimation: Effet de dégradé de rotation. Lors de la création, précisez les angles de rotation de début et de fin de l'animation, ainsi que la durée de l'animation et l'axe de rotation ; <rotate/>balises correspondantes
AnimationSet: Le dégradé combiné est une combinaison des dégradés précédents, correspondant au <set/>label

Code 2.xml et description de l'attribut : (Créer le répertoire anim sous res, nouveau fichier xml dans anim)

[Échec du transfert d'image par lien externe. Le site source peut avoir un mécanisme anti-sangsue. Il est recommandé de sauvegarder l'image et de la télécharger directement (img-4q5lhTok-1686710312405) (C:\Users\SW\AppData\Roaming\Typora\ typora-user-images\ image-20230526154902325.png)]

Insérer la description de l'image ici

Insérer la description de l'image ici

  1. AlphaAnimation:: anim_alpha.xml

    <?xml version="1.0" encoding="utf-8"?>
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromAlpha="1.0"
        android:toAlpha="0.1"
        android:duration = "3000"
        />
    
    fromAlpha : 起始透明度
    toAlpha : 结束透明度
    透明度的范围为:0-1,完全透明-完全不透明
    
  2. ScaleAnimation:anim_scale.xml

    <?xml version="1.0" encoding="utf-8"?>
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:fromXScale="0.2"
        android:toXScale="1.5"
        android:fromYScale="0.2"
        android:toYScale="1.5"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="2000"/>
    
    fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例
    toXScale/toYScale:沿着X轴/Y轴缩放的结束比例
    pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点
    
  3. TranslateAnimation: anim_translate.xml

    <?xml version="1.0" encoding="utf-8"?>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromXDelta="0"
        android:toXDelta="320"
        android:fromYDelta="0"
        android:toYDelta="-320"
        android:duration="2000"/>
    
    fromXDelta/fromYDelta:动画起始位置的X/Y坐标
    toXDelta/toYDelta:动画结束位置的X/Y坐标
    
  4. RotateAnimation:anim_rotate.xml

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromDegrees="0"
        android:toDegrees="129"
        android:duration="1000"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
    
    fromDegrees/toDegrees:旋转的起始/结束角度
    
    repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
    
    repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!
    
    
  5. AnimationSet: En fait, c'est une collection de plusieurs animations (et plusieurs animations commencent à jouer en même temps)

    anim_set.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:shareInterpolator="true" >
        <scale
            android:duration="2000"
            android:fromXScale="0.2"
            android:fromYScale="0.2"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toXScale="1.5"
            android:toYScale="1.5" />
        <rotate
            android:duration="1000"
            android:fromDegrees="0"
            android:repeatCount="1"
            android:repeatMode="reverse"
            android:toDegrees="360" />
        <translate
            android:duration="2000"
            android:fromXDelta="0"
            android:fromYDelta="0"
            android:toXDelta="320"
            android:toYDelta="0" />
        <alpha
            android:duration="2000"
            android:fromAlpha="1.0"
            android:toAlpha="0.1" />
    </set>
    
    android:shareInterpolator="true" : 为true时,set中的所有动画都共享同一插值器。 为false时,需要为set中每个动画都设置单独的插值器  (Interpolator)
    

3. Le code Java charge l'animation XML pour obtenir l'instance d'animation et la démarrer.

                //利用AnimationUtils从xml中加载获取Animation实例
               Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_alpha); 
               //调用view去开启动画 
               mImageView.startAnimation(animation);

Ce qui précède est le code Java pour charger l'animation anim_alpha.xml. Pareil pour d'autres choses

4. Créez directement des instances d'animation en Java

  1. RotateAnimation

                    RotateAnimation rotateAnimation = new RotateAnimation(0, 360);
                    rotateAnimation.setRepeatCount(1);
                    rotateAnimation.setRepeatMode(Animation.REVERSE);
                    rotateAnimation.setDuration(2000);
                    mImageView.startAnimation(rotateAnimation);
    
  2. AnimationSet

                    Animation rotateAnimation = new RotateAnimation(0, -720, RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
                    rotateAnimation.setDuration(2000);
                    Animation translateAnimation = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT, 0, TranslateAnimation.RELATIVE_TO_PARENT, 0.5f,
                            TranslateAnimation.RELATIVE_TO_PARENT, 0, TranslateAnimation.RELATIVE_TO_PARENT, 0.5f);
                    translateAnimation.setDuration(2000);
                    Animation scaleAnimation = new ScaleAnimation(0, 1.4f, 0, 1.4f, ScaleAnimation.RELATIVE_TO_SELF,
                            0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
                    scaleAnimation.setDuration(2000);
                    Animation alphaAnimation = new AlphaAnimation(0, 1);
                    alphaAnimation.setDuration(2000);
                    AnimationSet animationSet = new AnimationSet(true);
                    animationSet.addAnimation(rotateAnimation);
                    animationSet.addAnimation(translateAnimation);
                    animationSet.addAnimation(scaleAnimation);
                    animationSet.addAnimation(alphaAnimation);
                    animationSet.setDuration(4000);
                    animationSet.setFillAfter(false);
                    mImageView.startAnimation(animationSet);
    
  3. La même chose s'applique aux autres animations

5. Surveillance des animations interpolées

Appelez setAnimationListener (AnimationListener listening) de l'objet d'animation pour définir l'écouteur
           scaleAnimation.setAnimationListener(new Animation.AnimationListener() {
     
     
                    @Override
                    public void onAnimationStart(Animation animation) {
     
     
                        Log.d(TAG, "onAnimationStart:  开始" );
                    }

                    @Override
                    public void onAnimationEnd(Animation animation) {
     
     
                        Log.d(TAG, "onAnimationEnd:  结束");
                    }

                    @Override
                    public void onAnimationRepeat(Animation animation) {
     
     
                        Log.d(TAG, "onAnimationRepeat: 重复");
                    }
                });

​onAnimationStart () : appelé lorsque l'animation démarre

​onAnimtaionRepeat () : appelé lorsque l'animation est jouée à plusieurs reprises

​onAnimationEnd () : appelé à la fin de l'animation

S'il s'agit d'une animation répétée deux fois, alors onAnimtaionRepeat sera appelé deux fois, mais le début et la fin ne seront appelés qu'une seule fois.

3. Animation des attributs

1. ViewPropertyAnimateur

1. Utiliser

Son utilisation est relativement simple : View.animate()suivie d' translationX()autres méthodes, l'animation sera exécutée automatiquement. Par exemple:

            imageView.animate().translationYBy(-100).translationXBy(100).setDuration(3000)
                     .setInterpolator(new AccelerateDecelerateInterpolator()).start();

Les méthodes spécifiques qui peuvent être suivies et les Viewméthodes de fonctionnement réelles correspondant aux méthodes sont présentées dans la figure ci-dessous :

Insérer la description de l'image ici

Comme le montre la figure, Viewchaque méthode de correspond à ViewPropertyAnimatordeux méthodes de , dont l'une porte -Byle suffixe, par exemple, View.setTranslationX()correspond aux deux méthodes ViewPropertyAnimator.translationX()de et . ViewPropertyAnimator.translationXBy()La méthode avec -By()le suffixe est la version incrémentale de la méthode. Par exemple, cela signifie que la valeur de est progressivement augmentée translationX(100)par l'animation , et signifie que la valeur de est progressivement augmentée par l'animation .ViewtranslationX100translationXBy(100)ViewtranslationX100

Compréhension de l'image : si -Bycette méthode n'est pas utilisée, après avoir cliqué une fois pour lire l'animation, lorsque l'animation se termine (c'est-à-dire lorsque la valeur modifiée a atteint la valeur finale), l'animation ne sera pas jouée lorsque vous cliquez à nouveau pour lire l'animation. (car la valeur finale a été atteinte), ne changera plus). Cependant, si vous utilisez -Bycette méthode, l'animation sera toujours jouée si vous cliquez à nouveau, car à chaque fois que vous cliquez, les propriétés de la méthode correspondante augmenteront et elle "bougera".

Par exemple:

imageView.animate().translationYBy(-100).translationX(100).start();

Lorsque vous cliquez pour la première fois, x et y se déplacent. Après cela, seul y bougera à chaque fois que vous cliquerez. Parce que X a atteint la valeur finale après la première lecture et que Y est de -100 à chaque fois ;

2. Surveillance

setListener(new Animator.AnimatorListener() {
     
     
                     @Override
                     public void onAnimationStart(@NonNull Animator animation) {
     
     
                             Log.d(TAG, "onAnimationStart: 开始");
                     }

                     @Override
                     public void onAnimationEnd(@NonNull Animator animation) {
     
     
                             Log.d(TAG, "onAnimationEnd:   结束");
                     }

                     @Override
                     public void onAnimationCancel(@NonNull Animator animation) {
     
     
                             Log.d(TAG, "onAnimationCancel:  取消");
                     }

                     @Override
                     public void onAnimationRepeat(@NonNull Animator animation) {
     
     
                              Log.d(TAG, "onAnimationRepeat:  重复");
                         }
                     })

Les méthodes ci-dessus sont résumées plus tard

2.Animateur d'objet

Utilisation : code Java

  1. S'il s'agit d'un contrôle personnalisé, vous devez ajouter la méthode setter/ ;getter
  2. Utiliser pour ObjectAnimator.ofXXX()créer ObjectAnimatorun objet ; (doit avoir les méthodes setter et getter correspondantes)
  3. Utilisez start()la méthode pour réaliser des animations.
                animator =ObjectAnimator.ofFloat(imageView,"alpha",1f,0f,1f);
                animator.setDuration(5000); //过渡时间
                //动画延迟500ms执行
                animator.setStartDelay(500);
                //执行重复次数 +1
                animator.setRepeatCount(1);
                // 设置动画重复播放模式 RESTART -执行完一遍后重新执行
                // REVERSE -执行完一遍后 从末位置往前执行
                animator.setRepeatMode(ValueAnimator.REVERSE);
                animator.start();

Interpolateur Interpolator : setInterpolator(Interpolator interpolator)configuration d'appel

Le système fournit neuf différenciateurs par défaut comme suit :

Insérer la description de l'image ici

AccelerateDecelerateInterpolator : c'est la valeur par défautInterpolator

3. Configurez l'écouteur :

La méthode de définition d'un écouteur est légèrement différente ViewPropertyAnimatorde celle de : en utilisant la méthode et , vous pouvez définir un écouteur, et lorsque vous souhaitez supprimer l'écouteur, remplissez la valeur nulle pour le supprimer ; et utilisez et pour en ajouter un ou plusieurs. Listeners , pour supprimer l’écouteur, spécifiez l’objet à supprimer.ObjectAnimatorViewPropertyAnimatorsetListener()setUpdateListener()setUpdate]Listener(null)ObjectAnimatoraddListener()addUpdateListener()removeUpdateListener()

De plus, comme ObjectAnimatoril prend en charge la mise en pause à l'aide de la méthode, il dispose également d'un support / pause()supplémentaire ; et dispose d'une méthode and unique , qui peut configurer une surveillance ponctuelle du début ou de la fin de l'animation.addPauseListener()removePauseListener()ViewPropertyAnimatorwithStartAction(Runnable)withEndAction(Runnable)

3.1 ViewPropertyAnimator.setListener() / ObjectAnimator.addListener()

Les noms de ces deux méthodes sont différents et le nombre d'écouteurs pouvant être définis est également différent, mais leurs types de paramètres sont les mêmes AnimatorListener, ils sont donc essentiellement les mêmes. AnimatorListenerIl existe 4 méthodes de rappel :

3.1.1 onAnimationStart (animation de l'animateur)

Cette méthode est appelée lorsque l'animation commence à s'exécuter.

3.1.2 onAnimationEnd (animation de l'animateur)

Cette méthode est appelée à la fin de l'animation.

3.1.3 onAnimationCancel (animation de l'animateur)

cancel()Cette méthode est appelée lorsque l'animation est annulée via la méthode.

A noter que même si l'animation est annulée, onAnimationEnd()elle sera quand même appelée. Ainsi, lorsque l'animation est annulée, si elle est définie AnimatorListener, onAnimationCancel()les deux et onAnimationEnd()seront appelés. sera appelé onAnimationCancel()avant .onAnimationEnd()

3.1.4 onAnimationRepeat (animation de l'animateur)

Cette méthode est appelée lorsque l'animation est répétée via setRepeatMode()la méthode / setRepeatCount()ou .repeat()

Puisqu'elle ViewPropertyAnimatorne prend pas en charge la duplication, cette méthode est ViewPropertyAnimatoréquivalente à invalide.

                animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     
     
                    @Override
                    public void onAnimationUpdate(@NonNull ValueAnimator animation) {
     
     
                        Log.d(TAG, "onAnimationUpdate: " + animation.getAnimatedValue());
                    }
                });
                animator.addPauseListener(new Animator.AnimatorPauseListener() {
     
     
                    @Override
                    public void onAnimationPause(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationPause: ");
                    }

                    @Override
                    public void onAnimationResume(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationResume: ");
                    }
                });
                animator.addListener(new Animator.AnimatorListener() {
     
     
                    @Override
                    public void onAnimationStart(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationStart: ");
                    }

                    @Override
                    public void onAnimationEnd(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationEnd: ");
                    }

                    @Override
                    public void onAnimationCancel(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationCancel: ");
                    }

                    @Override
                    public void onAnimationRepeat(@NonNull Animator animation) {
     
     
                        Log.d(TAG, "onAnimationRepeat: ");
                    }
                });

3.2 ViewPropertyAnimator.setUpdateListener() / ObjectAnimator.addUpdateListener()

Comme les deux méthodes de 3.1 ci-dessus, bien que ces deux méthodes aient des noms et un nombre d'écouteurs réglables différents, leur essence est en fait la même et leurs paramètres sont les mêmes AnimatorUpdateListener. Il n'a qu'une seule méthode de rappel : onAnimationUpdate(ValueAnimator animation).

3.2.1 onAnimationUpdate (animation ValueAnimator)

Cette méthode est appelée lorsque les propriétés animées sont mises à jour.

Le paramètre de la méthode est one ValueAnimator, ValueAnimatorqui est ObjectAnimatorla classe parent de et ViewPropertyAnimatorl'implémentation interne de , donc ce paramètre est en fait ViewPropertyAnimatorcelui à l'intérieur ValueAnimator(incohérent avec l'instance de ViewPropertyAnimator), ou ObjectAnimatoril est lui-même pour (c'est-à-dire l'instance de paramètre de la méthode d'écoute est la même que celle de l'appel (ses instances sont les mêmes).

3.3 ObjectAnimator.addPauseListener()

3.4 ViewPropertyAnimator.withStartAction/EndAction (Runnable)

Ces deux méthodes sont ViewPropertyAnimatoruniques à . Il existe deux différences principales entre eux et le / set/addListener()dans le rappel :onAnimationStart()onAnimationEnd()

  1. withStartAction(Runnable)/ withEndAction(Runnable)est à usage unique et est automatiquement supprimé après l'exécution de l'animation. Même s'il est réutilisé ViewPropertyAnimatorultérieurement pour d'autres animations, les rappels définis avec eux ne seront plus appelés. Le set/addListener()paramètre AnimatorListenerest valable en permanence. Lorsque l'animation est exécutée à plusieurs reprises, le rappel sera toujours appelé.
  2. withEndAction(Runnable)Le rappel set ne sera appelé que lorsque l'animation se terminera normalement et ne sera pas exécuté lorsque l'animation sera annulée. Ceci AnimatorListener.onAnimationEnd()est incompatible avec le comportement de .

4. Obtenez ObjectAnimator via la méthode XML

Vous devez créer un animateur sous res, puis créer un fichier XML sous l'animateur :

Insérer la description de l'image ici

Insérer la description de l'image ici

Insérer la description de l'image ici

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="alpha"
    android:valueFrom="1"
    android:valueTo="0"
    android:valueType="floatType" />

acquisition de code java :

               animator = (ObjectAnimator) AnimatorInflater.loadAnimator(MainActivity.this,R.animator.animator_alpha); //xml方式 <ObjectAnimator>标签代码 objectAnimator
               animator.setTarget(imageView); //xml方式,需要加个Target

Révision : les animations interpolées sont chargées à l’aide de AnimationUtils.loadAnimation

Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.anim_alpha);

3.ValeurAnimateur

ValueAnimator (animation de valeur) réalise l'animation en contrôlant le changement de valeur puis en l'attribuant manuellement aux propriétés de l'objet.

Les méthodes principales du code Java de ValueAnimator sont les suivantes :

ValueAnimator ofFloat(float... values) // 浮点型数值
ValueAnimator  ofInt(int... values) // 整型数值
ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values) // 自定义对象类型

Utilisez le code Java pour obtenir ValueAnimator :

             anim = ValueAnimator.ofFloat(0f, 1f); 
             anim.setDuration(5000);
             anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
     
     
                 @Override
                 public void onAnimationUpdate(ValueAnimator animation) {
     
     
                     float currentValue = (float) animation.getAnimatedValue();
                     Log.d("MainActivity", "cuurent value is " + currentValue);
                     imageView.setAlpha(currentValue);
                 }
             });
             anim.start();

Utilisez XML pour obtenir ValueAnimator :

<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
 android:valueFrom="0f"
 android:valueTo="1f"
 android:valueType="floatType"
 />

2. Obtenez l'instance ValueAnimator en code Java :

anim =(ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.animator_value); //xml方式 <animator>标签代表 ValueAnimator

4.PropertyValuesHolder

PropertyValuesHolder La modification de plusieurs propriétés dans la même animation peut également être comprise comme le démarrage de plusieurs animations en même temps.

utiliser:

              PropertyValuesHolder alphaProper =  PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);
              PropertyValuesHolder scaleXProper = PropertyValuesHolder.ofFloat("scaleX", 0f, 1f);
              PropertyValuesHolder scaleYProper = PropertyValuesHolder.ofFloat("scaleY", 0f, 1f);
              PropertyValuesHolder translationXProper = PropertyValuesHolder.ofFloat("translationX", -100, 0);
              PropertyValuesHolder translationYProper = PropertyValuesHolder.ofFloat("translationY", -100, 0);
              PropertyValuesHolder rotationProper = PropertyValuesHolder.ofFloat("rotation", 0, 360);
              ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageView, alphaProper,
                      scaleXProper, scaleYProper,translationXProper,translationYProper,rotationProper);
              animator.setDuration(5000);
              animator.setRepeatCount(2);
              animator.setRepeatMode(ValueAnimator.REVERSE);
              animator.start();
public static ObjectAnimator ofPropertyValuesHolder(Object target,    PropertyValuesHolder... values)  //方法
Utilisation avancée : PropertyValuesHolders.ofKeyframe() divise la même propriété
             Keyframe keyframe1 = Keyframe.ofFloat(0f, 0);    //动画完成0,到达0
             Keyframe keyframe2 = Keyframe.ofFloat(1f, 100);  //动画完成100%到达100
             Keyframe keyframe = Keyframe.ofFloat(0.5f, 200); //动画完成50%到达200
             PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX", keyframe1, keyframe, keyframe2);
             ObjectAnimator animator2 = ObjectAnimator.ofPropertyValuesHolder(imageView, holder);
             animator2.setDuration(2000);
             animator2.start();

5.AnimateurEnsemble

AnimatorSet Plusieurs animations sont exécutées ensemble

Parfois, vous devez non seulement modifier plusieurs propriétés dans une animation, mais également plusieurs animations pour fonctionner ensemble. Par exemple, lorsque la taille du contenu est agrandie de 0 à 100 %, il commence à bouger. PropertyValuesHolderIl n'est pas possible de l'utiliser dans ce cas , car si ces attributs sont placés dans la même animation, ils doivent partager Interpolatorune série de paramètres tels que l'heure de début, l'heure de fin de l'animation, etc., afin que l'animation ne puisse pas être exécutée séquentiellement. .

AnimatorSet est donc nécessaire

               ObjectAnimator rotate = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360f);
               ObjectAnimator translationX = ObjectAnimator.ofFloat(imageView, "translationX", -100, 0);
               ObjectAnimator translationY = ObjectAnimator.ofFloat(imageView, "translationY", 0, -100);
               ObjectAnimator scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 0, 1f);
               ObjectAnimator scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 1, 0.5f);
               ObjectAnimator alpha = ObjectAnimator.ofFloat(imageView, "alpha", 1f, 0f, 1f);
               animSet = new AnimatorSet();
               animSet.play(rotate)
                       .with(alpha)
                       .before(scaleX)
                       .after(scaleY)
                       .with(translationX)
                       .before(translationY);
               animSet.setDuration(2000);
               animSet.start();
Remarque : le même niveau sera joué ensemble en même temps. Par exemple, si deux with sont définis, peu importe où ils sont placés, ils seront lus en même temps que l'animation transmise par play, comme après et avant.

6.Évaluateur TypeEvaluator

Concernant ObjectAnimator, il peut être utilisé ofInt()pour animer les propriétés des entiers et pour ofFloat()animer les propriétés décimales. Ces deux types d'attributs sont les plus couramment utilisés pour l'animation d'attributs.Cependant, dans le développement réel, il existe d'autres types qui peuvent être utilisés pour l'animation d'attributs. Lorsque vous devez animer des propriétés d’autres types, vous devez TypeEvaluatorl’ . Par exemple, changer la couleur, etc.

Utilisation : à l'aide de TypeEvaluatorl'animation d'attributs, vous pouvez ofObject()animer des attributs de types illimités via . La méthode est très simple :

  1. Écrivez-en un personnalisé pour l'attribut cibleTypeEvaluator
  2. Utiliser ofObject()pour créer Animatoret remplir les TypeEvaluatorparamètres personnalisés en tant que paramètres
ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values)
ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)

À partir du code source de l'évaluateur TypeEvaluator, nous pouvons voir que la fonction de cette classe est d'indiquer à l'animation comment passer de la valeur de départ à la valeur de fin.
Il existe plusieurs classes dans le code source Android qui implémentent cette interface, qui sont des évaluateurs par défaut fournis par le système. Prenons FloatEvaluator comme exemple pour examiner son code d'implémentation.

public class FloatEvaluator implements TypeEvaluator<Number> {
     
     
    public Float evaluate(float fraction, Number startValue, Number endValue) {
     
     
        float startFloat = startValue.floatValue();
        return startFloat + fraction * (endValue.floatValue() - startFloat);
    }
}

De l'implémentation de FloatEvaluator, nous pouvons voir que dans la méthode d'évaluation, la valeur finale est soustraite de la valeur initiale, la différence entre elles est calculée, puis multipliée par le coefficient de fraction, plus la valeur initiale, puis la valeur de l'animation actuelle est obtenue.

PS : La fraction est le degré d'achèvement, elle changera continuellement de 0 à 1

TypeEvaluator personnalisé : implémentez simplement TypeEvaluator et écrivez un algorithme personnalisé.

Par exemple : écrire un estimateur qui change de couleur

public class MyTypeEvaluator implements TypeEvaluator<String> {
     
     
    private int mCurrentRed = -1;
    private int mCurrentGreen = -1;
    private int mCurrentBlue = -1;
    @Override
    public String evaluate(float fraction, String startValue, String endValue) {
     
     
        Log.d("text", "evaluate: " + fraction);
        int startRed = Integer.parseInt(startValue.substring(1, 3), 16);
        int startGreen = Integer.parseInt(startValue.substring(3, 5), 16);
        int startBlue = Integer.parseInt(startValue.substring(5, 7), 16);
        int endRed = Integer.parseInt(endValue.substring(1, 3), 16);
        int endGreen = Integer.parseInt(endValue.substring(3, 5), 16);
        int endBlue = Integer.parseInt(endValue.substring(5, 7), 16);
        Log.d("TAG", "evaluate: " + startRed + "   " + startGreen + "    " + startBlue + "    "
         + endRed + "    " + endGreen + "   " +endBlue);
        // 初始化颜色的值
        if (mCurrentRed == -1) {
     
     
            mCurrentRed = startRed;
        }
        if (mCurrentGreen == -1) {
     
     
            mCurrentGreen = startGreen;
        }
        if (mCurrentBlue == -1) {
     
     
            mCurrentBlue = startBlue;
        }
        // 计算初始颜色和结束颜色之间的差值
        int redDiff = Math.abs(startRed - endRed);
        int greenDiff = Math.abs(startGreen - endGreen);
        int blueDiff = Math.abs(startBlue - endBlue);

        if (mCurrentRed != endRed) {
     
     
            mCurrentRed = getCurrentColor(startRed, endRed, redDiff, fraction);

        }
        if (mCurrentGreen != endGreen) {
     
     
            mCurrentGreen = getCurrentColor(startGreen, endGreen, greenDiff, fraction);

        }
        if (mCurrentBlue != endBlue) {
     
     
            mCurrentBlue = getCurrentColor(startBlue, endBlue,blueDiff, fraction);


        }
        Log.d("test", "evaluate: " + mCurrentRed + "    " + mCurrentGreen + "   "+mCurrentBlue);
        // 将计算出的当前颜色的值组装返回
        String currentColor = "#" + getHexString(mCurrentRed)
                + getHexString(mCurrentGreen) + getHexString(mCurrentBlue);
        return currentColor;
    }
    /**
     * 根据fraction值来计算当前的颜色。
     */
    private int getCurrentColor(int startColor, int endColor, int colorDiff, float fraction) {
     
     
        int currentColor;
        if (startColor > endColor) {
     
     
            currentColor = (int) (startColor - (fraction * colorDiff));
            if (currentColor <= endColor) {
     
     
                currentColor = endColor;
            }
        } else {
     
     
            currentColor = (int) (startColor + (fraction * colorDiff));
            if (currentColor >= endColor) {
     
     
                currentColor = endColor;
            }
        }
        return currentColor;
    }
    /**
     * 将10进制颜色值转换成16进制。
     */
    private String getHexString(int value) {
     
     
        String hexString = Integer.toHexString(value);
        if (hexString.length() == 1) {
     
     
            hexString = "0" + hexString;
        }
        return hexString;
    }
}

utiliser:

 ValueAnimator animator1 = ValueAnimator.ofObject( new MyTypeEvaluator(), "#123456", "#ABCDEF");
 animator1.setDuration(3000);
 animator1.start();

Vidéo de démonstration de l'animation de la propriété : non publique

Résumé des différences entre l'animation interpolation et l'animation d'attribut :

  1. Limitation des objets : l'animation d'interpolation de vue ne peut être utilisée que sur la vue, c'est-à-dire qu'elle ne peut animer qu'un bouton, un TextView ou même un LinearLayout, ou d'autres composants hérités de la vue, mais elle ne peut pas animer des objets non-View. Dans certains cas, l'effet d'animation n'est qu'un certain attribut et objet de la vue plutôt que la vue entière ; par exemple, si vous devez changer dynamiquement la couleur de la vue, vous devez utiliser l'attribut de couleur de la vue pour obtenir l'effet d'animation, plutôt que d'animer la vue entière.
  2. Elle ne modifie pas les propriétés de la vue mais modifie uniquement les effets visuels : l'animation d'interpolation modifie uniquement les effets visuels de la vue sans réellement modifier les propriétés de la vue. Par exemple, déplacer le bouton dans le coin supérieur gauche de l'écran vers le coin inférieur droit de l'écran via une animation d'interpolation n'a aucun effet. Cliquer sur la position actuelle du bouton (coin inférieur droit de l'écran) n'a aucun effet, car le bouton en réalité reste dans le coin supérieur gauche de l'écran et l'animation d'interpolation déplace simplement le bouton. Le dessiner dans le coin inférieur droit de l'écran modifie simplement l'effet visuel.
  3. Effet d'animation unique : l'animation interpolée ne peut répondre qu'à des exigences d'animation simples telles que la translation, la rotation, la mise à l'échelle et la transparence. L'animation de propriétés peut utiliser des estimateurs pour utiliser des algorithmes personnalisés afin de modifier d'autres propriétés (telles que la couleur, etc.)

Adresse du projet : non publique

Je suppose que tu aimes

Origine blog.csdn.net/XJ200012/article/details/131198776
conseillé
Classement