banner
jzman

jzman

Coding、思考、自觉。
github

Androidプロパティアニメーション

上一篇 では、Android フレームアニメーションと補間アニメーションに関する知識をまとめました。この記事では、プロパティアニメーションについて紹介します。プロパティアニメーションは、フレームアニメーションや補間アニメーションよりも強力です。フレームアニメーションと補間アニメーションは View およびそのサブクラスにのみ適用できますが、プロパティアニメーションは任意のオブジェクトのプロパティ値を変更できます。プロパティ値は指定された時間内に自動的に変化し、オブジェクトのプロパティ値の変化に基づいてより複雑なアニメーションを実現します。

  1. プロパティアニメーションの一般的な設定
  2. ValueAnimator
  3. ObjectAnimator
  4. キーフレーム
  5. 補間器と評価器

プロパティアニメーションの一般的な設定#

以下はプロパティアニメーションの一般的な設定です。

// プロパティアニメーションの持続時間を設定
animator.setDuration(2000);
// プロパティ補間器を設定
animator.setInterpolator(new AccelerateInterpolator());
// プロパティアニメーションの繰り返し再生モードを設定
animator.setRepeatMode(ValueAnimator.REVERSE);
// プロパティアニメーションの繰り返し再生回数を設定
animator.setRepeatCount(0);
// プロパティアニメーションの遅延再生時間を設定
animator.setStartDelay(0);
// プロパティアニメーションの評価器を設定し、最終プロパティ値を制御する(API22)
animator.setCurrentFraction(0.5f);
// 現在の再生時間を設定し、その値は Duration の範囲内
animator.setCurrentPlayTime(1000);
// プロパティアニメーションの評価器を設定し、最終プロパティ値を制御する
animator.setEvaluator(new IntEvaluator());
// プロパティアニメーションのリスナーを設定
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Log.i(TAG, animation.getAnimatedValue() + "");
        //
    }
});
//...

ValueAnimator#

ValueAnimator は、アニメーションを実行するためのシンプルなタイミングエンジンを提供し、設定された期間や他の属性に基づいてアニメーション値の計算を行います。その後、アニメーション値を適切なターゲットオブジェクトに設定できます。使用される補間器はデフォルトで AccelerateDecelerateInterpolator であり、アニメーションの開始時と終了時は遅く、中間で加速してアニメーションを完了します。以下はソースコード内のデフォルトの補間器です。

// アニメーションに設定されていない場合に使用される時間補間器
private static final TimeInterpolator sDefaultInterpolator =
        new AccelerateDecelerateInterpolator();

ValueAnimator では、いくつかの評価器 IntEvaluator と FloatEvaluator が内部で処理されています。つまり、ofInt および ofFloat メソッドをアニメーションのプロパティ値として使用する場合、ValueAnimator は自動的に int と float 値の変化を処理します。ソースコード内で確認したところ、この部分は PropertyValuesHolder クラスにあります。

void init() {
    if (mEvaluator == null) {
        // int と float は自動的に処理されますが、それらのオブジェクト
        // 等価物は処理されません
        mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
                (mValueType == Float.class) ? sFloatEvaluator :
                null;
    }
    if (mEvaluator != null) {
        // KeyframeSet は一般的な型を評価する方法を知っています - このクラスに設定されたカスタム
        // 評価器がある場合のみそれを与えます
        mKeyframes.setEvaluator(mEvaluator);
    }
}

ValueAnimator はコードを使用して作成することも、xml を使用して作成することもできます。以下は平行移動アニメーションの例で、ValueAnimator の使用方法を説明します。他の使用方法(スケーリング、回転など)も似ています。

コードを使用して作成#

private void translation(){
    ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100);
    valueAnimator.setDuration(2000);
    valueAnimator.setInterpolator(new AccelerateInterpolator());
    valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
    valueAnimator.setRepeatCount(0);
    valueAnimator.setStartDelay(0);
//    valueAnimator.setCurrentFraction(0.5f);
//    valueAnimator.setCurrentPlayTime(1000);
    valueAnimator.setEvaluator(new IntEvaluator());

    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG, animation.getAnimatedValue() + "");
            int x = (int) animation.getAnimatedValue();
            ivImage.setTranslationX(x);
            ivImage.setTranslationY(x);
        }
    });

    valueAnimator.start();
}

xml を使用して作成#

res/animator フォルダーに test_animator.xml ファイルを作成し、ファイル内容は以下の通りです。

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

    android:duration="2000"
    android:startOffset ="0"
    android:repeatMode = "reverse"
    android:repeatCount = "0"
    android:interpolator = "@android:anim/accelerate_interpolator">
</animator>

次に、Activity 内で ValueAnimator を取得し、ターゲットオブジェクトを設定してアニメーションを開始します。具体的には以下の通りです。

private void translation(){
    ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this,R.animator.test_animator);
    animator.setTarget(ivImage);
    animator.start();
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG, animation.getAnimatedValue() + "");
            int x = (int) animation.getAnimatedValue();
            ivImage.setTranslationX(x);
            ivImage.setTranslationY(x);
        }
    });
}

テスト効果#

ここでは ValueAnimator を使用して平行移動アニメーションを実現し、テスト効果は以下の通りです。

image

ObjectAnimator#

ObjectAnimator は ValueAnimator のサブクラスで、ターゲットオブジェクト上でアニメーションプロパティの設定をサポートします。そのコンストラクタでは、ターゲットオブジェクトと対応するアニメーションプロパティの名前を指定するパラメータを使用します。次に、対応するアニメーションプロパティの setter メソッドを実行してアニメーションを完了します。つまり、プロパティアニメーション ObjectAnimator は最終的にターゲットオブジェクトの setter メソッドを呼び出してターゲットオブジェクトのプロパティ値を変更し、ターゲットオブジェクトのプロパティを変更してアニメーション効果を実現します。以下は透明度の変化を紹介するための ObjectAnimator の基本的な使用法です。コードは以下の通りです。

private void alpha(){
    ObjectAnimator animator = ObjectAnimator.ofFloat(ivImage,"alpha",1f,0,1f);
    animator.setDuration(3000);
    // 他のプロパティアニメーションの設定
    //...
    animator.start();
}

以下はテスト効果の画像です。

image

平行移動、回転、スケーリングアニメーションの実装方法は基本的に上記の通りです。ここでは詳しく説明しませんが、対応する setter メソッドの関係は以下の通りです。

属性作用対応方法
AlphaView の透明度を制御setAlpha
TranslationXX 方向の移動を制御setTranslationX
TranslationYY 方向の移動を制御setTranslationY
ScaleXX 方向のスケーリング倍率を制御setScaleX
ScaleYY 方向のスケーリング倍率を制御setScaleY
Rotation画面方向を軸とした回転度数を制御setRotation
RotationXX 軸を軸とした回転度数を制御setRotationX
RotationYY 軸を軸とした回転度数を制御setRotationY

ObjectAnimator は多くの ofXxx () メソッドを提供して、プロパティアニメーションの設定を容易にします。以下の画像を参照してください。

image

異なるアニメーションのニーズに応じて、ObjectValueAnimator の異なる ofXxx () メソッドを使用して対応するアニメーションを実現できます。

キーフレーム#

ここではキーフレームの使用について簡単に説明します。キーフレームとは、特定の固定時刻に具体的なプロパティ値を定義することを指します。定義されたキーフレームは、評価器が返す値に基づいてプロパティ値を返します。プロパティアニメーションにおけるキーフレームの使用方法は以下の通りです。

/**
 * キーフレームの使用
 */
private void keyFrame(){
    Keyframe keyframe1 = Keyframe.ofFloat(0,0);
    Keyframe keyframe2 = Keyframe.ofFloat(0.25f,300);
    // 各 KeyFrame は独自の補間器を設定できます
    keyframe2.setInterpolator(new AccelerateInterpolator());
    Keyframe keyframe3 = Keyframe.ofFloat(0.75f,100);
    Keyframe keyframe4 = Keyframe.ofFloat(1,400);
    PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationX",keyframe1,keyframe2,keyframe3,keyframe4);
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(ivImage,holder);
    animator.setDuration(3000);
    animator.start();
}

キーフレームを追加した後の通常の平行移動アニメーションの変化を見てみましょう。テスト効果は以下の通りです。

image

補間器と評価器#

  • 補間器 (TimeInterpolator) は、アニメーション全体の期間におけるアニメーションの変化の法則を示します。たとえば、加速や減速などです。

Android には多くの組み込み補間器があり、これらの補間器は実際の開発におけるほとんどの状況をカバーしています。具体的には以下の通りです。

image

組み込みの補間器がニーズを満たさない場合は、カスタム補間器を作成することもできます。

  • 評価器 (TypeEvaluator) は、アニメーション全体の期間における各時点のプロパティ値の具体的な変化を示します。

ここでは、View が正弦曲線に沿って移動するカスタム評価器を作成します。カスタム評価器は以下の通りです。

/**
 * カスタム評価器
 * Point は座標 x と y をカプセル化しています
 */
public class SineTypeValue implements TypeEvaluator<Point> {
    @Override
    public Point evaluate(float fraction, Point startValue, Point endValue) {
        // y = sinA
        float distance = fraction * (endValue.getX() - startValue.getX());
        float x = startValue.getX() + distance;
        float y = startValue.getY() + (float) Math.sin(distance / 100 * Math.PI) * 100;
        Point point = new Point();
        point.setX(x);
        point.setY(y);
        return point;
    }
}

次に、アニメーションにこの評価器を設定し、アニメーションプロパティをリスニングして View の位置を設定することで、View が正弦曲線に沿って移動するアニメーションを実現します。使用方法は以下の通りです。

/**
 * カスタム評価器の使用
 * 正弦運動の評価器
 */
private void sina(){
    Point startPoint = new Point(ivImage.getX(),ivImage.getY());
    Point endPoint = new Point(ivImage.getX()+500,ivImage.getY());
    ValueAnimator valueAnimator = ValueAnimator.ofObject(new SineTypeValue(), startPoint, endPoint);
    valueAnimator.setDuration(5000);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Log.i(TAG, animation.getAnimatedValue() + "");
            Point point = (Point) animation.getAnimatedValue();
            ivImage.setX(point.getX());
            ivImage.setY(point.getY());
        }
    });
    valueAnimator.start();
}

テスト効果は以下の通りです。

image

Android のプロパティアニメーションのまとめはここで終了です。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。