Androidのフレームアニメーション、トゥイーンアニメーション、属性アニメーションの使い方と概要について。(ソースコード添付)

※内容が多いので、分割してお読みいただけますが、後から3回に分けて読むことも可能です。

1.Androidアニメーションまとめ

1.フレームアニメーション

フレーム アニメーションは、実際に画像を連続再生することでアニメーション効果をシミュレートします。

これを実現するには、次の 2 つの方法があります。

1.xmlファイル方式

  1. まずdrawable配下にanimation_lufi.xmlを作成します。

    <?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>
    

    効果をプレビューできます。

ここに画像の説明を挿入します

  1. レイアウト ファイルのビューに背景としてanimation_lufi.xmlを追加します。

    <?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. Javaコードでアニメーションを取得する

    animationDrawable = (AnimationDrawable) img.getBackground();
    
  3. このアニメーションを使用してください

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

2. Javaコードメソッド

  1. 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. その他の用途は変わりません。インスタンスの取得方法とフレームの追加方法が異なるだけです。

2.トゥイーンアニメーション

トゥイーン アニメーションの開発者は、アニメーションの開始と終了の「キー フレーム」を指定するだけでよく、アニメーションの変更の「中間フレーム」はシステムによって計算されて完了します。

1.トゥイーンアニメーションの種類

AlphaAnimation:: 透明度のグラデーション効果、作成時の開始と終了の透明度、アニメーションの継続時間、透明度の変更範囲 (0,1) を指定します。0 は完全に透明、1 は完全に不透明です。対応するラベルは<alpha/>!
ScaleAnimation: スケール グラデーション エフェクト作成時に、開始と終了のスケーリング率、スケーリング基準点、およびアニメーションの継続時間を指定する必要があります。対応するラベル<scale/>!
TranslateAnimation:ディスプレイスメントグラデーションエフェクト、作成時の開始位置と終了位置の指定、アニメーションの継続時間の指定、対応<translate/>ラベル!
RotateAnimation: 回転グラデーション効果作成時にアニメーションの開始角度と終了角度、アニメーション時間と回転軸を指定し、対応するタグを指定します<rotate/>
AnimationSet<set/>: 結合されたグラデーションは、ラベルに対応する前のグラデーションの組み合わせです。

2.xml コードと属性の説明: (res の下に anim ディレクトリを作成し、anim に新しい xml ファイルを作成します)

[外部リンク画像の転送に失敗しました。ソース サイトにはリーチ防止メカニズムが存在する可能性があります。画像を保存して直接アップロードすることをお勧めします (img-4q5lhTok-1686710312405) (C:\Users\SW\AppData\Roaming\Typora\) typora-user-images\ image-20230526154902325.png)]

ここに画像の説明を挿入します

ここに画像の説明を挿入します

  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: 実際には、これは複数のアニメーションのコレクションです (複数のアニメーションが同時に再生されます)。

    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. Java コードは XML アニメーションをロードしてアニメーション インスタンスを取得し、開始します。

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

上記は、anim_alpha.xml アニメーションをロードするための Java コードです。他のことについても同様

4. 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. 他のアニメでも同様です

5. トゥイーンアニメーションのモニタリング

アニメーションオブジェクトのsetAnimationListener(AnimationListenerlistener)を呼び出してリスナーを設定します
           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 (): アニメーションの開始時に呼び出されます

onAnimtaionRepeat (): アニメーションが繰り返し再生されるときに呼び出されます

onAnimationEnd (): アニメーションの終了時に呼び出されます

2 回繰り返されるアニメーションの場合、onAnimtaionRepeat は2 回呼び出されますが、start と end は 1 回だけ呼び出されます。

3. 属性アニメーション

1.ViewPropertyAnimator

1. 使用する

使用方法は比較的簡単です。他のメソッドView.animate()を使用するとtranslationX()、アニメーションが自動的に実行されます。例えば:

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

具体的な方法とそれViewに対応した実際の操作方法を以下の図に示します。

ここに画像の説明を挿入します

図からわかるように、Viewの各メソッドはViewPropertyAnimatorの 2 つのメソッドに対応し、そのうちの 1 つには-Byサフィックスが付いています。たとえば、と の2 つのメソッドView.setTranslationX()に対応します。接尾辞が付いているメソッドは、そのメソッドのインクリメンタル版であり、例えば、アニメーションによって の値徐々に増加することを意味しアニメーションによって の値徐々に増加することを意味しますViewPropertyAnimator.translationX()ViewPropertyAnimator.translationXBy()-By()translationX(100)ViewtranslationX100translationXBy(100)ViewtranslationX100

画像の理解:-Byこの方法を使用しない場合、一度クリックしてアニメーションを再生した後、アニメーションが終了したとき(つまり、変更した値が終了値に達したとき)、もう一度クリックしてアニメーションを再生してもアニメーションは再生されません。 (終了値に達したため、再度変更されません)。ただし、このメソッドを使用すると-By、クリックするたびに対応するメソッドのプロパティが増加して「移動」するため、もう一度クリックしてもアニメーションが再生されます。

例えば:

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

初めてクリックすると、x と y の両方が移動します。以降、クリックするたびにyだけが移動します。最初の再生後に X が終了値に達し、Y は毎回 -100 になるためです。

2. モニタリング

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:  重复");
                         }
                     })

上記の方法は後ほどまとめます

2.オブジェクトアニメーター

使用法: Java コード

  1. カスタム コントロールの場合は、setter/getterメソッドを追加する必要があります。
  2. オブジェクトObjectAnimator.ofXXX()の作成に使用します(対応する setter メソッドと getter メソッドが必要です)ObjectAnimator
  3. start()メソッドを使用してアニメーションを実行します。
                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();

インターポレータ Interpolator: コールsetInterpolator(Interpolator interpolator)セットアップ

システムには、次の 9 つのデフォルトの差別化要素が用意されています。

ここに画像の説明を挿入します

AccelerateDecelerateInterpolator: これがデフォルトですInterpolator

3. リスナーを設定します。

リスナーの設定方法は、の方法ViewPropertyAnimatorとはObjectAnimator少し異なりますViewPropertyAnimator。 and メソッドを使用してリスナーを設定し、リスナーを削除する場合はnull 値を入力して削除し、 and を使用して1 つ以上のリスナーを追加します。 listens 、リスナーを削除するには、削除するオブジェクトを指定します。setListener()setUpdateListener()setUpdate]Listener(null)ObjectAnimatoraddListener()addUpdateListener()removeUpdateListener()

さらに、メソッドをObjectAnimator使用した一時停止をサポートしているため、追加の/サポートもあり、アニメーションの開始または終了の 1 回限りの監視を設定できる独自のandメソッドもあります。pause()addPauseListener()removePauseListener()ViewPropertyAnimatorwithStartAction(Runnable)withEndAction(Runnable)

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

この 2 つのメソッドは名前が異なり、設定できるリスナーの数も異なりますが、パラメータの型が同じであるため、AnimatorListener本質的には同じです。AnimatorListenerコールバック メソッドは 4 つあります。

3.1.1 onAnimationStart(アニメーターアニメーション)

このメソッドは、アニメーションの実行が開始されるときに呼び出されます。

3.1.2 onAnimationEnd(アニメーターアニメーション)

このメソッドはアニメーションの終了時に呼び出されます。

3.1.3 onAnimationCancel(アニメーターアニメーション)

このメソッドは、アニメーションがメソッドによってキャンセルされたcancel()ときに呼び出されます。

なお、アニメーションがキャンセルされてもonAnimationEnd()呼び出されます。したがって、アニメーションがキャンセルされると、 が設定されている場合AnimatorListeneronAnimationCancel()と の両方がonAnimationEnd()呼び出されます。onAnimationCancel()の前にonAnimationEnd()呼び出されます。

3.1.4 onAnimationRepeat(アニメーターアニメーション)

このメソッドは、アニメーションがsetRepeatMode()/ setRepeatCount()orメソッドを介して繰り返されるときに呼び出されます。repeat()

は重複をサポートしていないためViewPropertyAnimator、このメソッドはViewPropertyAnimator無効に相当します。

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

上記 3.1 の 2 つのメソッドと同様に、この 2 つのメソッドは名前と設定可能なリスナーの数が異なりますが、本質は同じであり、パラメータも同じですAnimatorUpdateListenerコールバック メソッドは 1 つだけです: onAnimationUpdate(ValueAnimator animation)

3.2.1 onAnimationUpdate(ValueAnimator アニメーション)

このメソッドは、アニメーション化されたプロパティが更新されるときに呼び出されます。

メソッドのパラメータは one でValueAnimatorValueAnimatorこれはObjectAnimatorの親クラスであり、ViewPropertyAnimatorの内部実装です。そのため、このパラメータは実際にはViewPropertyAnimator内部のものValueAnimator(ViewPropertyAnimator インスタンスと矛盾)、またはObjectAnimatorそれ自体 (つまり、パラメータ インスタンス) です。リスニングメソッドのインスタンスは呼び出しメソッドと同じです)。

3.3 ObjectAnimator.addPauseListener()

3.4 ViewPropertyAnimator.withStartAction/EndAction(実行可能)

これら 2 つの方法ViewPropertyAnimatorは に固有のものです。これらとset/addListener()コールバックのonAnimationStart()/のonAnimationEnd()間には、主に 2 つの違いがあります。

  1. withStartAction(Runnable)/withEndAction(Runnable)は 1 回限りの使用であり、アニメーションの実行後に自動的に破棄されます。後でViewPropertyAnimator他のアニメーションで再利用したとしても、それらで設定されたコールバックが再び呼び出されることはありません。設定set/addListener()AnimatorListener継続的に有効となり、アニメーションを繰り返し実行する場合には必ずコールバックが呼び出されます。
  2. withEndAction(Runnable)設定したコールバックはアニメーションが正常に終了した場合にのみ呼び出され、アニメーションがキャンセルされた場合には実行されません。これはAnimatorListener.onAnimationEnd()の動作と矛盾します。

4. XML メソッドを通じて ObjectAnimator を取得する

res の下にアニメーターを作成し、そのアニメーターの下に xml ファイルを作成する必要があります。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

ここに画像の説明を挿入します

<?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" />

Javaコードの取得:

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

復習: トゥイーン アニメーションは、AnimationUtils.loadAnimation を使用してロードされます。

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

3.バリューアニメーター

ValueAnimator(値アニメーション)は、値の変化を制御し、オブジェクトのプロパティに手動で割り当てることでアニメーションを実現します。

ValueAnimator の Java コードのコア メソッドは次のとおりです。

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

Java コードを使用して 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();

XML を使用して 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. Java コードで ValueAnimator インスタンスを取得します。

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

4.PropertyValuesHolder

PropertyValuesHolder 同じアニメーション内で複数のプロパティを変更することは、複数のアニメーションを同時に開始することとしても理解できます。

使用:

              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)  //方法
高度な使用法: PropertyValuesHolders.ofKeyframe() は同じプロパティを分割します
             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.アニメーターセット

AnimatorSet 複数のアニメーションをまとめて実行します

場合によっては、1 つのアニメーションで複数のプロパティを変更する必要があるだけでなく、コンテンツのサイズを 0 から 100% に拡大すると動き始めるなど、複数のアニメーションを連携させる必要もあります。この場合は使用できPropertyValuesHolderません。これらの属性を同じアニメーション内に配置するInterpolatorと、アニメーションの開始時間、終了時間などの一連の設定を共有する必要があり、アニメーションを連続して実行できないためです。 。

したがってAnimatorSetが必要です

               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();
注: 同じレベルは同時に一緒にプレイされます。たとえば、with が 2 つ設定されている場合、どこに配置されていても、前後と同様に、play によって渡されたアニメーションと同時に再生されます。

6.TypeEvaluator エバリュエーター

ofInt()ObjectAnimator に関しては、整数のプロパティをアニメーション化したり、10 進数のプロパティをアニメーション化したりするために使用できますofFloat()これら 2 つの属性タイプは、属性アニメーションに最もよく使用される 2 つですが、実際の開発では、属性アニメーションに使用できる他のタイプも存在します。他のタイプのプロパティをアニメーション化する必要がある場合は、TypeEvaluatorそれを。例えば、色を変えるなど。

使用法:TypeEvaluator属性アニメーションを使用すると、 を通じて無制限のタイプの属性をアニメーション化できますofObject()方法は非常に簡単です。

  1. ターゲット属性のカスタム属性を作成します。TypeEvaluator
  2. カスタムのものを作成してパラメータとして入力するofObject()ために使用しますAnimatorTypeEvaluator
ValueAnimator  ofObject(TypeEvaluator evaluator, Object... values)
ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)

TypeEvaluator エバリュエーターのソース コードから、このクラスの機能は開始値から終了値への遷移方法をアニメーションに指示することであることがわかります。
Android ソース コードには、このインターフェイスを実装するいくつかのクラスがあり、これらはシステムによって提供されるいくつかのデフォルト エバリュエーターです。実装コードを見てみるために FloatEvaluator を例として取り上げます。

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

FloatEvaluator の実装から、evaluate メソッドで、初期値から最終値が減算され、それらの差が計算され、その後、分数の係数、初期値、および次の値が乗算されることがわかります。現在のアニメーションが取得されます。

PS: 分数は完成度で、0から1まで連続的に変化します。

カスタム TypeEvaluator: TypeEvaluator を実装し、カスタム アルゴリズムを記述するだけです。

例: 色を変える推定器を作成します。

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

使用:

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

プロパティアニメーションのデモビデオ:非公開

トゥイーン アニメーションと属性アニメーションの違いの概要:

  1. オブジェクトの制限: ビュー トゥイーン アニメーションはビューでのみ使用できます。つまり、Button、TextView、LinearLayout、または View から継承されたその他のコンポーネントのみをアニメーション化できますが、View 以外のオブジェクトをアニメーション化することはできません。場合によっては、アニメーション効果はビュー全体ではなく、ビューの特定の属性とオブジェクトのみです。たとえば、ビューの色を動的に変更する必要がある場合、ビューの色属性を操作して実現する必要があります。ビュー全体をアニメーション化するのではなく、アニメーション効果を操作します。
  2. ビューのプロパティは変更されませんが、視覚効果のみが変更されます。トゥイーン アニメーションは、ビューのプロパティを実際に変更することなく、ビューの視覚効果のみを変更します。たとえば、トゥイーン アニメーションによって画面の左上隅にあるボタンを画面の右下隅に移動しても効果はありません。現在のボタンの位置 (画面の右下隅) をクリックしても、実際にはボタンが配置されているため、効果はありません。は画面の左上隅に留まり、トゥイーン アニメーションはボタンを移動するだけです。ボタンを画面の右下隅に描画すると、視覚効果が変わるだけです。
  3. 単一のアニメーション効果: トゥイーン アニメーションでは、移動、回転、スケーリング、透明度などの単純なアニメーション要件のみを実現できます。プロパティ アニメーションでは、エスティメーターを使用してカスタム アルゴリズムを使用し、他のプロパティ (色など) を変更できます。

プロジェクトアドレス: 非公開

おすすめ

転載: blog.csdn.net/XJ200012/article/details/131198776