ケルベロスさんのプログラミング / けるぷろ

プログラマのけるさんことケルベロスです

Androidアニメーションの基礎

Androidアニメーションの基礎

使用する主なクラス

android.animation.Animator
android.animation.ValueAnimator
android.animation.ObjectAnimator

ObjectAnimatorはValueAnimatorのサブクラス
ValueAnimatorはObjectAnimatorのサブクラス

+ Animator  
    ↓  
    + ValueAnimator  
            ↓  
          * ObjectAnimator  

Animator

ValueAnimatorやObjectAnimatorの基底クラスで状態変化のリスナなどの機能を持つ

ValueAnimator

アニメーション化された値を計算し、ターゲットオブジェクト上に設定するアニメーションを実行するための簡単なタイミングエンジンを提供するクラス

ObjectAnimator

ターゲットオブジェクトと値と実際にアニメーションプロパティをコンストラクタで受け取り、内部的に適切な関数を実行してアニメーションを実行するクラス

アニメーションに使用するプロパティ

相対的な位置変更: translationX & translationY
絶対的な位置変更: x, y
回転 :rotation, rotationX, rotationY
サイズ変更 :scaleX, scaleY
支点 :pivotX, pivotY
透明度 :alpha

実装してみる

透明度

透明からだんだん表示されるアニメーション

private Animator alphaAnimator(View target) {
    float fromAlpha = 0f;
    float toAlpha = 1f;
    ObjectAnimator animator = ObjectAnimator.ofFloat(target,"alpha",fromAlpha,toAlpha);  // ->(1)
    animator.setDuration(1000);                                                          // ->(2)
    return animator;
}

(1) ObjectAnimator.ofFloatの引数は
+ アニメーションするターゲットオブジェクト
+ アニメーション前の値
+ アニメーション後の値

(2) animator.setDurationで1000msecかけてアニメーションするように設定している

回転

回転し続けるアニメーション

private Animator rotateAnimator(View target) {
    ObjectAnimator  animator = ObjectAnimator.ofFloat(target, "rotation", 0f,360f);
    animator.setDuration(1000);
    animator.setRepeatCount(ValueAnimator.INFINITE);
    return animator;
}

animator.setRepeatCountにINFINITEを指定して回転し続けるように指定している

移動

移動するアニメーション

private Animator translateAnimator(View target, float distance, float degree) {
    float fromX = 0f;
    float fromY = 0f;
    float toX = (float) (distance * Math.cos(Math.toRadians(degree)));
    float toY = (float) (distance * Math.sin(Math.toRadians(degree)));
    
    PropertyValuesHolder xHolder = PropertyValuesHolder.ofFloat("translationX",fromX,toX); // ->(3)
    PropertyValuesHolder yHolder = PropertyValuesHolder.ofFloat("translationY",fromY,toY);

    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(target,xHolder,yHolder);
    animator.setDuration(1000);
    animator.setInterpolator(new BounceInterpolator());                                    // ->(4)

    return animator
}

(3) Y軸の変更とX軸の変更を同時に行なっている
その場合はPropertyValuesHolderを使用して、ObjectAnimator.ofPropertyValuesHolderの引数に入れてAnimatorを初期化する
(4) animator.setInterpolatorでアニメーションカーブを設定することができる
+ AccelerateDecelerateInterpolator
なにも設定しなかった場合のデフォルトの挙動 加速したのちに減速してアニメーションを終える
+ DecelerateInterpolator
最初に加速してだんだん減速する
+ AccelerateInterpolator
だんだん加速する
+ BounceInterpolator
バウンドするように加速減速逆方向移動を繰り返して目標の値に到達する
+ OvershootInterpolator
目標の値を一旦オーバーしてから目的の値に到達する

全て組み合わせる

透明な状態から回転しながら目的の位置に移動する

private void alphaTranslateRotateAnimation(View target, float distance, float degree, long delay) {

    Animator alpha = alphaAnimator(target);

    Animator translate = translateAnimator(target,distance,degree);

    Animator rotate = rotateAnimator(target);

    AnimatorSet set = new AnimatorSet();                     // ->(5)
    set.setStartDelay(delay);                                // ->(6)
    set.setInterpolator(new OvershootInterpolator());
    set.playTogether(alpha,translate,rotate);                // ->(7)

    set.start();

}

(5) AnimatorSetは複数のAnimatorを束ねて同時に実行したり順番に実行したりすることができるいわゆる管理クラス
Animatorを継承しているので上記説明した設定も行える
(6) setStartDelayでアニメーション実行開始時間の遅延時間を設定する
(7) playTogetherは引数に入れたAnimatorを同時に実行する設定
playSequentiallyで順番に実行させることもできる

サンプルプロジェクト

上記アニメーションを使用するサンプルプロジェクトをgithubに置いたので参考にしていただければと思います。
実装内容は、ボタンを押すと放射線状に他のボタンが現れるメニューボタンのようなアニメーションです
rdme/AnimationSample: Android Sample Application

参考

ObjectAnimator | Android Developers
素人からAndroidアニメーションの面白さを発見しよう - Qiita
AndroidでもiPhoneに負けないようなアニメーションを実装してみよう - Yahoo! JAPAN Tech Blog