プロパティ アニメーションの概要

Compose の方法を試す
Jetpack Compose は、Android で推奨される UI ツールキットです。Compose でアニメーションを使用する方法について学習します。
<ph type="x-smartling-placeholder"></ph> Animation*AsState →

プロパティ アニメーション システムは、ほぼすべてをアニメーション化できる堅牢なフレームワークです。オブジェクトのプロパティを時間とともに変化させるアニメーションを定義できます。 画面に描画されるかどうかに関係なくプロパティ アニメーションは、指定された時間の長さにわたってプロパティの(オブジェクトのフィールドの)値を変更します。オブジェクトをアニメーション化するには、画面上のオブジェクトの位置、アニメーション化する長さ、アニメーション化する値など、アニメーション化するオブジェクトのプロパティを指定します。

プロパティ アニメーション システムを使用すると、 アニメーション:

  • 継続時間: アニメーションの長さを指定できます。デフォルトの長さは 300 ms です。
  • 時間補間: プロパティの値をアニメーションの現行経過時間の関数として計算する方法を指定できます。
  • 繰り返し回数と動作: アニメーションが継続時間の最後に達したときにアニメーションを繰り返すかどうかと、アニメーションを繰り返す回数を指定できます。また、 アニメーションを逆方向に再生するかどうかを指定します。リバースに設定すると、繰り返し回数に達するまで、アニメーションの再生と巻き戻しを繰り返します。
  • アニメーター セット: アニメーションを論理セットにグループ化して、まとめて再生、順に再生、または指定した遅延の後に再生できます。
  • フレーム更新遅延: アニメーションのフレームを更新する頻度を指定できます。「 デフォルトでは 10 ミリ秒ごとに更新するよう設定されていますが、アプリケーションでフレームを更新できる速度は 最終的には、システム全体のビジー状態と、基になるタイマーをシステムがどれだけ速く処理できるかに依存します。

プロパティ アニメーションの完全な例については、 CustomTransitionChangeColor クラス ご覧ください。

プロパティ アニメーションの仕組み

まず、簡単な例を使用してアニメーションの仕組みについて説明します。図 1 は、画面上の水平方向の位置を表す x プロパティを使用して、アニメーション化される仮想オブジェクトを示しています。アニメーションの持続時間は 40 ms に設定されており、距離は 40 ピクセルです。デフォルトのフレーム更新頻度である 10 ms ごとに、オブジェクトが水平方向に 10 ピクセルずつ移動します。40 ミリ秒が経過すると、アニメーションは停止し、オブジェクトは 水平方向は 40 番ですこれは線形補間を使用するアニメーションの例であり、オブジェクトが一定の速度で移動することを意味します。

図 1. 線形アニメーションの例

非線形補間を行うアニメーションを指定することもできます。図 2 は、 アニメーションの開始時に加速し、 終わります。オブジェクトは 40 ms で 40 ピクセル移動しますが、非線形です。 このアニメーションは中間点まで加速し、 アニメーションが終了します。図 2 に示すように、アニメーションの開始時と終了時の移動距離は、中間よりも短くなります。

図 2. 非線形アニメーションの例

プロパティ アニメーション システムの重要なコンポーネントが、 は、上に示したようなアニメーションを計算します。図 3 は、メインクラスが互いにどのように機能するかを示しています。

図 3. アニメーションの計算方法

ValueAnimator オブジェクトは、アニメーションの実行時間やアニメーション化されるプロパティの現在の値など、アニメーションのタイミングをトラッキングします。

ValueAnimator は、アニメーションの補間を定義する TimeInterpolator と、アニメーション化するプロパティの値を計算する方法を定義する TypeEvaluator をカプセル化します。たとえば図 2 では、使用する TimeInterpolatorAccelerateDecelerateInterpolatorTypeEvaluatorIntEvaluator になります。

アニメーションを開始するには、ValueAnimator を作成し、 アニメーション化するプロパティの開始値と終了値、 追加します。start() を呼び出すと、アニメーションが開始されます。ValueAnimator はアニメーションの全体で、アニメーションの継続時間と経過時間に基づいて、0 から 1 の間で経過した割合を計算します。「 経過時間の割合は、アニメーションが完了した時間の割合を表します。0 は 0% を意味します。 1 は 100%を意味しますたとえば、図 1 では、t = 10 ms での経過時間の割合は 0 .25 になります。 時間の合計は t = 40 ミリ秒です。

ValueAnimator で経過した割合の計算が完了すると、 現在設定されている TimeInterpolator を呼び出し、 補間された割合です。補間された割合は、設定された時間補間を考慮して、経過した割合を新しい割合にマッピングします。たとえば、図 2 では、 アニメーションはゆっくりと加速するため、補間される割合(約 0 .15)は t = 10 ms で 0.25 と表した。図 1 では、補間された割合は常に 経過した割合を返します

補間された割合が計算されるとき、ValueAnimator は以下を呼び出します。 適切な TypeEvaluator を使用して、 値に基づいて、アニメーション化するプロパティを アニメーションの終了値を指定します。たとえば、図 2 では、t = 10 ミリ秒なので、その時点でのプロパティの値は 0.15 × (40 - 0)、つまり 6 になります。

プロパティ アニメーションとビュー アニメーションの違い

ビュー アニメーション システムでは View オブジェクトのみをアニメーション化できるため、View 以外のオブジェクトをアニメーション化するには、独自のコードを実装する必要があります。また、ビュー アニメーション システムでは、View オブジェクトの一部のアスペクト(ビューのスケーリングや回転など)のみをアニメーション化でき、背景色はアニメーション化できません。

ビュー アニメーション システムのもう 1 つのデメリットは、 実際のビュー自体ではなく、ビューが描画された。たとえば、画面上を移動するようにボタンをアニメーション化した場合、ボタンは正しく描画されますが、ボタンをクリックできる実際の場所は変わりません。そのため、独自のロジックを実装する必要があります。

プロパティ アニメーション システムでは、こうした制約が完全に削除され、 任意のオブジェクト(ビューとビュー以外)のすべてのプロパティと、オブジェクト自体が実際に変更される。 プロパティ アニメーション システムは、アニメーションの実行方法も堅牢です。ちなみに 大まかに言うと、色、 位置、サイズを指定し、補間やサイズなどのアニメーションの 複数のアニメーターを同期できます。

しかし、ビュー アニメーション システムのほうが設定に時間がかからず、作成に必要なコードも少なくて済みます。ビュー アニメーションで必要な処理がすべて完了している場合、または既存のコードがすでに意図したとおり動作している場合は、プロパティ アニメーション システムを使用する必要はありません。また、 ユースケースが発生した場合は、それぞれの状況で両方のアニメーション システムを使用するのが合理的です。

API の概要

プロパティ アニメーション システムの API のほとんどは、android.animation にあります。ビュー アニメーション システムでは、すでに多くの補間が android.view.animation に定義されているため、プロパティ アニメーション システムでもこれらの補間を使用できます。プロパティ アニメーション システムの主なコンポーネントを次の表に示します。

Animator クラスは、アニメーションを作成するための基本構造を提供します。このクラスは、最低限の機能しか提供しないため、通常は直接使用しません。 値のアニメーション化を完全にサポートするように拡張する必要がある機能。次のサブクラスは Animator を拡張します。

表 1. アニメーター

クラス 説明
ValueAnimator プロパティ アニメーション用のメインのタイミング エンジンで、 プロパティをアニメーション化します。アニメーションを計算するためのコア機能をすべて備えている 値が含まれ、各アニメーションのタイミングの詳細、 アニメーションの繰り返し、更新イベントを受信するリスナー、 評価できます。プロパティをアニメーション化するには、2 つの部分があります。 アニメーション化するオブジェクトとプロパティにそれらの値を設定します。ValueAnimatorは 2 曲目を演奏しないので、あなたが聴いてください ValueAnimator によって計算された値と、 アニメーション化するオブジェクトを 独自のロジックで変更できます詳細については、ValueAnimator を使用したアニメーション化をご覧ください。
ObjectAnimator ターゲットを設定できる ValueAnimator のサブクラス オブジェクトとオブジェクトプロパティを アニメーション化しますこのクラスは、変更に応じてプロパティを更新します。 アニメーションの新しい値を計算します。ターゲット オブジェクトの値をアニメーション化する処理がずっと簡単になるため、ほとんどの場合に ObjectAnimator を使用します。ただし、 ObjectAnimator には特定の制限(特定の IP アドレスの使用など)の制限があるため、ValueAnimator を直接使用することもできます。 アクセサ メソッドをターゲット オブジェクトに存在する必要があります。
AnimatorSet 互いに関連して実行されるようにアニメーションをグループ化するメカニズムを提供します。アニメーションは、まとめて再生する、順に再生する、または指定した遅延の後に再生するように設定できます。詳細については、AnimatorSet を使用して複数のアニメーションを演出するのセクションをご覧ください。

評価者は、特定のプロパティの値の計算方法をプロパティ アニメーション システムに指示する プロパティです。Animator クラスから提供されるタイミング データ、アニメーションの開始値と終了値を取得し、このデータに基づいてプロパティのアニメーション値を計算します。プロパティ アニメーション システムには、次のエバリュエータが用意されています。

表 2. エバリュエータ

クラス / インターフェース 説明
IntEvaluator int プロパティの値を計算するデフォルトのエバリュエータ。
FloatEvaluator float プロパティの値を計算するデフォルトのエバリュエータ。
ArgbEvaluator 表現されるカラー プロパティの値を計算するデフォルトのエバリュエータ 16 進値で指定します
TypeEvaluator 独自のエバリュエータを作成できるインターフェース。アニメーションを intfloat、color以外のオブジェクト プロパティ TypeEvaluator インターフェースを実装して、 オブジェクト プロパティのアニメーション値を計算します。また、デフォルトの動作とは異なる方法で処理する場合は、intfloat、color の値にカスタムの TypeEvaluator を指定することもできます。詳細については、TypeEvaluator を使用するのセクションをご覧ください。 カスタム エバリュエータの作成方法をご覧ください。

時間インターポレータは、アニメーションの特定の値を時間の関数として計算する方法を定義します。たとえば、アニメーション全体で線形に発生するアニメーションを指定できます。つまり、アニメーション全体で均等に移動します。また、アニメーションの開始時に加速し、終了時に減速するなど、非線形の時間を使用するアニメーションを指定することもできます。表 3 に、android.view.animation に含まれるインターポレータを示します。指定された interpolator がいずれも TimeInterpolator インターフェースを実装して、独自のインターフェースを作成します。カスタム インターポレータの記述方法の詳細については、インターポレータを使用するをご覧ください。

表 3: interpolator

クラス / インターフェース 説明
AccelerateDecelerateInterpolator 変化の速度の開始と終了はゆっくりですが、加速する interpolator 表示されます。
AccelerateInterpolator 変化の速度が緩やかで始めて 加速します
AnticipateInterpolator 変化が逆方向に開始してから、順方向に切り替わるインターポレータ。
AnticipateOvershootInterpolator 変化が逆転し、はじめて前進し、オーバーシュートする interpolator 最終的に最終的な値に戻ります
BounceInterpolator 変化が最後にバウンドするインターポレータ。
CycleInterpolator 指定したサイクル数だけアニメーションが繰り返されるインターポレータ。
DecelerateInterpolator 変化の速度が速く開始し、その後に開始される interpolator 減速します。
LinearInterpolator 変化の速度が一定であるインターポレータ。
OvershootInterpolator 変化が順方向に進み、最終値を過ぎてから戻るインターポレータ。
TimeInterpolator 独自のインターポレータを実装できるインターフェース。

ValueAnimator を使用してアニメーション化する

ValueAnimator クラスを使用すると、アニメーション化に使用する intfloat、または color の値のセットを指定することで、アニメーションの継続時間中に一部のタイプの値をアニメーション化できます。ValueAnimator を取得するには、そのファクトリ メソッド(ofInt()ofFloat()ofObject())のいずれかを呼び出します。例:

Kotlin

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

Java

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

このコードでは、start() メソッドが実行されたときに、ValueAnimator がアニメーションの値(0 から 100 まで)の計算を開始します。継続時間は 1,000 ms です。

次のようにして、アニメーション化するカスタムタイプを指定することもできます。

Kotlin

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

Java

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

このコードでは、start() メソッドが実行されたときに、MyTypeEvaluator によるロジックを使用して ValueAnimator がアニメーションの値(startPropertyValue から endPropertyValue まで)の計算を開始します。継続時間は 1,000 ms です。

このアニメーションの値を使用するには、 AnimatorUpdateListener ValueAnimator オブジェクトに追加します。 コード:

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

onAnimationUpdate() メソッドを使用すると、更新されたアニメーション値にアクセスし、 ビューの一つですリスナーの詳細については、アニメーション リスナーのセクションをご覧ください。

ObjectAnimator を使用してアニメーション化する

ObjectAnimatorValueAnimator(前のセクションで説明)のサブクラスであり、 エンジンと ValueAnimator の値計算に加え、次の機能を備えています。 ターゲット オブジェクトの名前付きプロパティをアニメーション化します。これにより、アニメーション化されたプロパティが自動的に更新されるため、ValueAnimator.AnimatorUpdateListener を実装する必要がなくなり、オブジェクトのアニメーション化が非常に簡単になります。

ObjectAnimator のインスタンス化は ValueAnimator と似ていますが、オブジェクトとそのプロパティの名前も指定します( 次の要素の間でアニメーション化する値を指定します。

Kotlin

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

Java

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

ObjectAnimator でプロパティを更新する 次のことを行う必要があります。

  • アニメーション化するオブジェクト プロパティには、 set<PropertyName>()ObjectAnimator はアニメーション中にプロパティを自動的に更新するため、このセッター メソッドでプロパティにアクセスできる必要があります。たとえば、プロパティ名が foo の場合、次の操作を行う必要があります。 setFoo() メソッドがある。このセッター メソッドが存在しない場合は、 オプション: <ph type="x-smartling-placeholder">
      </ph>
    • セッター メソッドをクラスに追加する権限がある場合は、追加する。
    • 変更する権限があるラッパークラスを使用し、そのラッパーが有効なセッター メソッドで値を受け取り、元のオブジェクトに転送するようにする。
    • 代わりに ValueAnimator を使用する。
  • ObjectAnimator ファクトリ メソッドのいずれかで values... パラメータの値を 1 つだけ指定した場合、その値がアニメーションの終了値と見なされます。したがって、アニメーション化するオブジェクト プロパティには、アニメーションの開始値を取得するために使用するゲッター関数が必要です。ゲッター関数は get<PropertyName>() の形式。たとえば、プロパティ名が foo には、getFoo() メソッドが必要です。
  • アニメーション化するプロパティのゲッター メソッド(必要な場合)とセッター メソッドには、 ObjectAnimator に指定した開始値と終了値と同じ型で動作する。たとえば、次の ObjectAnimator を作成する場合は、targetObject.setPropName(float)targetObject.getPropName() が必要です。
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • アニメーション化するプロパティまたはオブジェクトによっては、ビューで invalidate() メソッドを呼び出して、 更新されたアニメーション値。これは onAnimationUpdate() コールバックで行います。たとえばドローアブル オブジェクトの色のプロパティをアニメーション化すると、そのオブジェクトが再描画されたときにのみ、画面が更新されます。ビューのすべてのプロパティ セッター setAlpha() および setTranslationX() View は適切に無効化されるので、これらの呼び出しの際に View を無効にする必要はありません。 メソッドを新しい値に置き換えます。リスナーの詳細については、アニメーション リスナーのセクションをご覧ください。

AnimatorSet を使用して複数のアニメーションを演出する

多くの場合、別のアニメーションの開始またはタイミングに依存するアニメーションを再生する必要があります。 終了します。Android システムではアニメーションをまとめて AnimatorSet にバンドルできるため、アニメーションを同時に開始するか、順に開始するか、指定した遅延の後に開始するかを指定できます。AnimatorSet オブジェクトを相互にネストすることもできます。

次のコード スニペットは、次のように Animator オブジェクトを再生します。

  1. bounceAnim を再生する。
  2. squashAnim1squashAnim2stretchAnim1stretchAnim2 を同時に再生する。
  3. bounceBackAnim を再生する。
  4. 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();

アニメーション リスナー

下記のリスナーを使用して、アニメーションの継続時間中に重要なイベントをリッスンできます。

  • Animator.AnimatorListener
    • onAnimationStart() - アニメーションの開始時に呼び出されます。
    • onAnimationEnd() - アニメーションの終了時に呼び出されます。
    • onAnimationRepeat() - アニメーションが繰り返されるときに呼び出されます。
    • onAnimationCancel() - アニメーションがキャンセルされたときに呼び出されます。キャンセルされたアニメーション onAnimationEnd() も呼び出します。 その終了方法に関係なく
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - アニメーションのすべてのフレームで呼び出されます。このイベントをリッスンして、アニメーション中に ValueAnimator によって生成された計算値を使用します。値を使用するには、イベントに渡された ValueAnimator オブジェクトをクエリし、getAnimatedValue() メソッドで現在のアニメーション化された値を取得します。実装すると、 ValueAnimator を使用する場合はリスナーが必要です。

      アニメーション化するプロパティまたはオブジェクトによっては、ビューで invalidate() を呼び出して、アニメーション化された値で画面の領域を再描画する必要があります。たとえば、 Drawable オブジェクトの color プロパティを使用すると、 再描画します。setAlpha()setTranslationX() など、ビューのプロパティ セッターはすべてビューを適切に無効化するため、新しい値でこれらのメソッドを呼び出すとき、ビューを無効にする必要はありません。

Animator.AnimatorListener インターフェースのメソッドをすべて実装するわけではない場合、Animator.AnimatorListener インターフェースを実装する代わりに AnimatorListenerAdapter クラスを拡張できます。AnimatorListenerAdapter クラスには、オーバーライドを選択できるメソッドの空の実装が用意されています。

たとえば、次のコード スニペットは、onAnimationEnd() コールバックだけの AnimatorListenerAdapter を作成します。

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

ViewGroup オブジェクトへのレイアウト変更をアニメーション化する

プロパティ アニメーション システムには、ViewGroup オブジェクトへの変更をアニメーション化する機能が用意されています。 View オブジェクト自体を簡単にアニメーション化することもできます。

LayoutTransition クラスを使用して、ViewGroup 内のレイアウト変更をアニメーション化できます。ViewGroup 内のビューは、 アセットを追加または追加する際に、表示と非表示のアニメーションが ViewGroup から削除したり、View の setVisibility() メソッド VISIBLEINVISIBLE、または GONE。また ViewGroup 内の残りのビューは、ビューを追加または削除したとき、新しい位置にアニメーション化できます。1 対 1 の LayoutTransition オブジェクト内の次のアニメーション setAnimator() を呼び出す そして、Animator オブジェクトを 次の LayoutTransition 定数を使用します。

  • APPEARING - 指定されたアイテムで実行されるアニメーションを示すフラグ。 表示されます。
  • CHANGE_APPEARING - 指定されたアイテムで実行されるアニメーションを示すフラグ。 新しいアイテムがコンテナに表示されると変更されます。
  • DISAPPEARING - コンテナから消えるアイテムで実行されるアニメーションを示すフラグ。
  • CHANGE_DISAPPEARING - コンテナからアイテムが消えることで変化するアイテムで実行されるアニメーションを示すフラグ。

この 4 種類のイベントに対して独自のカスタム アニメーションを定義して、レイアウト遷移の外観をカスタマイズしたり、アニメーション システムにデフォルトのアニメーションを使用するように伝えたりできます。

属性に対して android:animateLayoutchanges 属性を true に設定するには、 ViewGroup では、次の処理を行います。

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

この属性を true に設定すると、ViewGroup に追加または ViewGroup から削除されたビューと、ViewGroup の残りのビューが自動的にアニメーション化されます。

StateListAnimator を使用してビューの状態の変化をアニメーション化する

StateListAnimator クラスを使用すると、実行時に実行されるアニメーターを定義できます。 ビューの状態を変更できます。このオブジェクトは、コンテンツの Animator オブジェクトが返され、指定された場合にそのアニメーションが ビュー状態(「押下」や「フォーカス」など)の変更。

StateListAnimator は、ルート <selector> 要素と子 <item> 要素(それぞれが StateListAnimator クラスで定義される異なるビュー状態を指定します)を持つ XML リソースで定義できます。各 <item> には、プロパティ アニメーション セットの定義が含まれています。

たとえば次のファイルは、ビューが押されたときに x と y のスケールを変更する状態リスト アニメーターを作成します。

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>

状態リスト アニメーターをビューにアタッチするには、次のように android:stateListAnimator 属性を追加します。

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

これで、このボタンの実行時に animate_scale.xml で定義されたアニメーションが使用されるようになりました。 必要があります。

または、コード内のビューに状態リスト アニメーターを割り当てるには、 AnimatorInflater.loadStateListAnimator() メソッドを実行し、アニメーターを View.setStateListAnimator() メソッドを使用してビューを作成します。

または、ビューのプロパティをアニメーション化する代わりに、AnimatedStateListDrawable を使用して、状態の変更の間にドローアブル アニメーションを再生できます。一部のシステム ウィジェットは Android 5.0 では、これらのアニメーションがデフォルトで使用されます。次の例は、AnimatedStateListDrawable を 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>

TypeEvaluator を使用する

Android システムで認識されていないタイプをアニメーション化する場合は、 TypeEvaluator インターフェースを実装してエバリュエータを作成します。データの取り込み時に intfloat、または色があります。 IntEvaluatorFloatEvaluatorArgbEvaluator の各タイプでサポートされている 評価担当者に提供します

TypeEvaluator インターフェースに実装するメソッドは evaluate() メソッドだけです。これにより、使用しているアニメーターが、アニメーションの現在のポイントでアニメーション化されたプロパティに適切な値を返すことができます。FloatEvaluator クラスは、 方法は次のとおりです。

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

注: ValueAnimator(または ObjectAnimator)を実行すると、アニメーションの現在の経過した割合が計算され、使用しているインターポレータに応じて補間バージョンが計算されます。補間された割合は、fraction パラメータを通じて TypeEvaluator が受け取るものであるため、アニメーション化された値を計算するときにインターポレータを考慮する必要はありません。

インターポレータを使用する

interpolator は、アニメーション内の特定の値を あります。たとえば、アニメーション全体で線形に発生するアニメーションを指定できます。つまり、アニメーションは全体を通して均等に移動します。また、非線形の時間を使用するアニメーションを指定することもできます。たとえば、アニメーションの開始時や終了時に加速や減速を使用します。

アニメーション システムの interpolator は、Animator から アニメーションの経過時間。interpolator は、タイプに一致するようにこの割合を アニメーションを追加しますAndroid システムには、一般的な interpolator のセットが android.view.animation package。上記のいずれも TimeInterpolator インターフェースを実装して、 あります。

例として、デフォルトのインターポレータである AccelerateDecelerateInterpolatorLinearInterpolator が補間された割合を計算する方法を比較します。LinearInterpolator は、経過した割合には影響しません。AccelerateDecelerateInterpolator はアニメーションを加速させ、 減速します。次のメソッドは、これらのインターポレータのロジックを定義します。

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

次の表は、これらのモデルによって計算される近似値を示しています。 interpolator を設定すると、1,000 ミリ秒続くアニメーションを作成できます。

経過時間(ms) 経過した割合 / 補間された割合(線形) 補間された割合(加速 / 減速)
0 0 0
200 .2 .1
400 .4 .345
600 .6 .654
800 .8 .9
1000 1 1

表に示すように、LinearInterpolator は値を変更します。 200 ミリ秒経過するたびに 0.2 の速度になります。AccelerateDecelerateInterpolator は、200ms から 600ms では LinearInterpolator よりも速く値を変更し、600ms から 1,000ms では遅く変更します。

キーフレームを指定する

Keyframe オブジェクトは、時間と値のペアで構成されます。これにより、 特定の時点の状態を指定します。各キーフレームには独自の interpolator を使用して、直前のアニメーションと キーフレームの時刻とキーフレームの時刻を指定します。

Keyframe オブジェクトをインスタンス化するには、いずれかのファクトリを使用する必要があります。 メソッド、ofInt()ofFloat()、または ofObject() を使用して、適切なタイプの Keyframe を取得します。その後、 ofKeyframe() ファクトリ メソッド PropertyValuesHolder オブジェクトを取得します。オブジェクトを取得したら、PropertyValuesHolder オブジェクトとアニメーション化するオブジェクトを渡すことで、アニメーターを取得できます。次のコード スニペットは、これを行う方法を示しています。

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

ビューをアニメーション化する

プロパティ アニメーション システムを使用すると、View オブジェクトのアニメーションを合理化できます。また、 いくつか利点がありますビュー アニメーション システムでは、ビュー オブジェクトの描画方法を変更することで、ビュー オブジェクトを変換しました。これは ビュー自体には操作するプロパティがないため、各ビューのコンテナで処理されます。 その結果、ビュー オブジェクトはアニメーション化されましたが、ビュー オブジェクト自体は変更されませんでした。これにより、オブジェクトが画面の別の場所に描画されていても、元の場所に残っているように動作しました。Android 3.0 ではこの欠点を解消するために、新しいプロパティと、対応するゲッター メソッドとセッター メソッドが追加されました。

プロパティ アニメーション システム View オブジェクトの実際のプロパティを変更することで、画面上の View をアニメーション化できます。イン さらに、ビューは自動的に invalidate() メソッドを使用して、プロパティが変更されるたびに画面を更新します。プロパティ アニメーションを容易にする View クラスの新しいプロパティは次のとおりです。

  • translationXtranslationY: これらのプロパティは、レイアウト コンテナによって設定されているビューの左と上の座標からの差分として、ビューの位置を制御します。
  • rotationrotationXrotationY: これらのプロパティ ピボット ポイントを中心とした 2D(rotation プロパティ)と 3D の回転を制御します。
  • scaleXscaleY: これらのプロパティは、ピボット ポイントを中心としたビューの 2D スケーリングを制御します。
  • pivotXpivotY: これらのプロパティは、 このピボット ポイントを中心にして、回転とスケーリングの変換が行われます。デフォルトでは、ピボット ポイントはオブジェクトの中心に配置されます。
  • xy: これらは、イベントを記述するためのシンプルなユーティリティ プロパティです。 コンテナ内のビューの最終的な位置。 translateX と translateY の値。
  • alpha: ビューのアルファ透明度を表します。デフォルトの値は 1(不透明)で、値 0 は完全な透明(非表示)を表します。

色や回転の値など、ビュー オブジェクトのプロパティをアニメーション化するには、プロパティ アニメーターを作成し、アニメーション化するビュー プロパティを指定するだけで済みます。例:

Kotlin

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

Java

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

アニメーターの作成について詳しくは、 ValueAnimatorObjectAnimator があります。

ViewPropertyAnimator を使用してアニメーション化する

ViewPropertyAnimator を使用すると、複数の画像を簡単にアニメーション化できます。 1 つの基になる Animator を使用して、View のプロパティを並列で処理します。 渡されます。これは ObjectAnimator と同様に動作します。これは、 ビューのプロパティの実際の値が使用されますが、同じ位置にある多くのプロパティをアニメーション化する方が 1 回だけです。さらに、ViewPropertyAnimator を使用するコードのほうが、はるかに簡潔で読みやすくなります。次のコード スニペットは、複数の環境変数を使用する場合と、 ObjectAnimator オブジェクト、 ObjectAnimator であり、次の場合の ViewPropertyAnimator ビューの x プロパティと y プロパティを同時にアニメーション化します。

複数の 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();

1 つの 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);

ViewPropertyAnimator の詳細については、対応する Android デベロッパー ブログの投稿をご覧ください。

XML でアニメーションを宣言する

プロパティ アニメーション システムでは、XML を使用してプロパティ アニメーションを宣言できます。 できます。XML でアニメーションを定義すると、アニメーションを簡単に再利用できます。 アニメーション シーケンスを簡単に編集できます。

Android 3.1 以降では、新しいプロパティ アニメーション API を使用するアニメーション ファイルを、従来のビュー アニメーション フレームワークを使用するアニメーション ファイルと区別するために、プロパティ アニメーションの XML ファイルを res/animator/ ディレクトリに保存する必要があります。

次のプロパティ アニメーション クラスでは、 次の XML タグ:

XML 宣言で使用できる属性を確認するには、アニメーション リソースをご覧ください。次の例では、2 つのオブジェクト アニメーションを再生します。 最初のネストされたセットで、2 つのオブジェクト アニメーションを同時に再生します。

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

このアニメーションを実行するには、アニメーション セットを開始する前に、コード内の XML リソースを AnimatorSet オブジェクトにインフレートしてから、すべてのアニメーションの対象オブジェクトを設定する必要があります。setTarget() を呼び出すと、便宜上、AnimatorSet のすべての子に対して単一の対象オブジェクトが設定されます。次のコードに、その方法を示します。

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

次の例に示すように、XML で ValueAnimator を宣言することもできます。

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

コードで以前の ValueAnimator を使用するには、次のコードに示すように、オブジェクトをインフレートし、AnimatorUpdateListener を追加し、更新されたアニメーション値を取得して、それをビューのいずれかのプロパティで使用する必要があります。

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

プロパティ アニメーションを定義するための XML 構文については、アニメーション リソースをご覧ください。

UI パフォーマンスに及ぶおそれのある影響

UI を更新するアニメーションでは、 指定します。このため、リソースを大量に消費するアニメーションを使用すると、アプリのパフォーマンスに悪影響を及ぼすおそれがあります。

UI をアニメーション化するために必要な作業が、レンダリング パイプラインのアニメーション ステージに追加されます。アニメーションが アプリのパフォーマンスを向上させるには、[GPU レンダリングのプロファイル作成] を有効にします。 モニタリングします。詳細については、GPU レンダリングのプロファイル作成のチュートリアルをご覧ください。