banner
jzman

jzman

Coding、思考、自觉。
github

Androidフレームアニメーションと補間アニメーション

Android は 3 種類のアニメーションを提供しています:フレームアニメーション、補間アニメーション、プロパティアニメーション。本記事ではフレームアニメーションと補間アニメーションの使用について紹介し、プロパティアニメーションの使用については後の記事で共有します。それでは、これら 2 つのアニメーションの使用を復習しましょう。

  1. FrameAnimation
  2. TweenAnimation
  3. まとめ

FrameAnimation#

FrameAnimation は逐次アニメーションで、簡単に言うと画像の動作順に従って再生されるアニメーションです。FrameAnimation を作成するには、XML で定義することも、コードを直接使用することもできます。

XML でフレームアニメーションを作成#

res/drawable フォルダー内に drawable ファイルを作成し、animation-list タグを使用します。具体的な内容は以下の通りです:

<?xml version="1.0" encoding="utf-8"?>
<!--FrameAnimator-->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@drawable/zzlx1"
        android:duration="100" />
    <item
        android:drawable="@drawable/zzlx2"
        android:duration="100" />
    <item
        android:drawable="@drawable/zzlx3"
        android:duration="100" />
    <!--...-->
</animation-list>

属性 oneshot が true の場合、アニメーションは 1 回だけ再生され、false の場合はアニメーションがループ再生されます。drawable は現在の動作に対応する画像で、duration はその持続時間です。duration の長さはアニメーションの再生速度に影響します。その後、Activity 内でこの drawable ファイルに対応する AnimationDrawable を取得し、AnimationDrawable オブジェクトを使用してアニメーションの状態を制御します。参考として以下のようになります:

//フレームアニメーションファイルに対応するAnimationDrawableを取得
mAnimationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.frame_animator);
//AnimationDrawableを画像の背景に設定
imageView.setBackground(mAnimationDrawable);

//アニメーションを開始
mAnimationDrawable.start();
//アニメーションを停止
mAnimationDrawable.stop();

コードでフレームアニメーションを作成#

コードでフレームアニメーションを作成するには、AnimationDrawable オブジェクトを作成し、AnimationDrawable 内に対応するフレームを追加するだけです。コードは以下の通りです:

//コードでフレームアニメーションを作成
mAnimationDrawable = new AnimationDrawable();
//アニメーションをループ再生するように設定、trueはアニメーションを1回だけ再生
mAnimationDrawable.setOneShot(false);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.zzlx1),100);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.zzlx2),100);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.zzlx3),100);
//...
imageView.setBackground(mAnimationDrawable);

//アニメーションを開始
mAnimationDrawable.start();
//アニメーションを停止
mAnimationDrawable.stop();

FrameAnimation の効果は以下の通りです:

image

TweenAnimation#

TweenAnimation は一般的に言われる補間アニメーションで、主に以下の種類があります:

  1. 移動アニメーション (Translation)
  2. 拡大縮小アニメーション (Scale)
  3. 回転アニメーション (Rotate)
  4. 不透明度アニメーション (Alpha)
  5. 組み合わせアニメーション

上記のアニメーションにはそれぞれ特有の属性があります。以下にこれらのアニメーションで共通するいくつかの属性を示します:

<!--アニメーションの持続時間を設定-->
android:duration="1200"
<!--アニメーション開始の遅延-->
android:startOffset ="1000"
<!--アニメーションが終了位置に戻るかどうか、デフォルトはtrue。fillBeforeがfalseに設定されている場合、アニメーションは終了位置に留まりません。これはバグかもしれません-->
android:fillBefore = "true"
<!--アニメーションが終了位置に戻るかどうか、デフォルトはfalse。fillAfterがtrueに設定されている場合、アニメーションは終了位置に留まります-->
android:fillAfter = "false"
<!--fill...属性が有効かどうかを設定。fillAfterには無効-->
android:fillEnabled= "true"
<!--アニメーションの繰り返しモードを設定。restartは再再生、reverseは逆再生で、repeatCountと組み合わせて使用-->
android:repeatMode = "restart"
<!--アニメーションの繰り返し回数を設定-->
android:repeatCount = "0"
<!--アニメーションの補間器を設定。ここでは、アニメーション開始時の速度が遅く、後で加速します-->
android:interpolator = "@android:anim/accelerate_interpolator"

コードでアニメーションを実装する場合、これらの属性にも対応する属性設定がありますので、直接設定すれば大丈夫です。

移動アニメーション (Translate)#

移動アニメーションは View の水平方向または垂直方向の位置を平行移動させるもので、開始位置と終了位置を指定できます。XML で移動アニメーションを定義することも、コードで移動アニメーションを作成することもできます。移動アニメーションに対応する Animation のサブクラスは TranslateAnimation です。

XML で移動アニメーションを定義:res/anim 内に translation_anim.xml という XML ファイルを作成し、そのファイル内で移動アニメーションを以下のように定義します:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:startOffset ="0"
    android:fillBefore = "true"
    android:fillAfter = "false"
    android:fillEnabled= "false"
    android:repeatMode = "reverse"
    android:repeatCount = "5"
    android:interpolator = "@android:anim/accelerate_interpolator"

    android:fromXDelta="0"
    android:fromYDelta="0"
    android:toXDelta="100"
    android:toYDelta="100">

上記の XML ファイルは移動アニメーションファイルを定義しており、移動アニメーション特有の属性の意味は以下の通りです:

<!--水平方向アニメーション開始位置-->
android:fromXDelta="0"
<!--垂直方向アニメーション開始位置-->
android:fromYDelta="0"
<!--水平方向アニメーション終了位置-->
android:toXDelta="100"
<!--垂直方向アニメーション終了位置-->
android:toYDelta="100"

その後、Activity 内でこの XML ファイルに対応する TranslateAnimation を取得し、それを設定したい View に設定すれば大丈夫です。具体的には以下の通りです:

private void translation(){
    //animで定義されたアニメーションファイルを取得
    TranslateAnimation translateAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.translation_anim);
    //アニメーションを設定して開始
    ivImage.startAnimation(translateAnimation);    
}

コードで移動アニメーションを作成:コードで移動アニメーションを作成するには、Animation のサブクラス TranslateAnimation を使用し、直接 TranslateAnimation オブジェクトを作成すれば大丈夫です。具体的には以下の通りです:

//コードで移動アニメーションを作成
private void translation(){
    //View自身の原点(View左上角)からのピクセルオフセットを示します
    TranslateAnimation translateAnimation = new TranslateAnimation(0,100,0,100);
    //アニメーションの持続時間を設定
    translateAnimation.setDuration(1200);
    //アニメーションの繰り返しモードを設定
    translateAnimation.setRepeatMode(Animation.REVERSE);
    //アニメーションの繰り返し回数を設定
    translateAnimation.setRepeatCount(3);
    translateAnimation.setFillAfter(true);
    //アニメーションの補間器を設定
    translateAnimation.setInterpolator(this,android.R.anim.accelerate_interpolator);
//        translateAnimation.setInterpolator(new AccelerateInterpolator());
    //...
    ivImage.startAnimation(translateAnimation);    
}

上記のパラメータで使用されているのはピクセルのオフセットで、API は View 自身と親 View に対するパーセンテージの設定方法も提供しています。以下のように TranslateAnimation オブジェクトを作成する方法は、上記の実装と同じ効果を持ちます。具体的には以下の通りです:

/**
 * ABSOLUTE:View自身の原点(View左上角)からのピクセルオフセットを示します
 *          この場合、TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)と同じです
 * RELATIVE_TO_SELF:View自身のパーセンテージを示します。例えば0.5fはView自身のサイズの50%、1.0fはView自身のサイズを示します
 * RELATIVE_TO_PARENT:親Viewに対するパーセンテージを示します。例えば0.5fはView自身のサイズの50%、1.0fはView自身のサイズを示します
 */
TranslateAnimation translateAnimation = new TranslateAnimation(
        Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0.46f,
        Animation.RELATIVE_TO_SELF,0,Animation.RELATIVE_TO_SELF,0.46f);

使用時には必要に応じて適切なコンストラクタを選択して TranslateAnimation を作成できます。テスト効果は以下の通りです:

image

拡大縮小アニメーション (Scale)#

拡大縮小アニメーションは View に対して視覚的に一定の程度で拡大または縮小します。XML で移動アニメーションを定義することも、コードで移動アニメーションを作成することもできます。拡大縮小アニメーションに対応する Animation のサブクラスは ScaleAnimation です。

XML で拡大縮小アニメーションを定義:res/anim 内に scale_anim.xml という XML ファイルを作成し、その中で拡大縮小アニメーションを以下のように定義します:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:startOffset ="0"
    android:fillBefore = "true"
    android:fillAfter = "false"
    android:fillEnabled= "false"
    android:repeatMode = "reverse"
    android:repeatCount = "3"
    android:interpolator = "@android:anim/accelerate_interpolator"

    android:fromXScale="1"
    android:fromYScale="1"
    android:toXScale="3"
    android:toYScale="3"
    android:pivotX="50%"
    android:pivotY="50%">
</scale>

上記の XML ファイルは拡大縮小アニメーションファイルを定義しており、拡大縮小アニメーション特有の属性の意味は以下の通りです:

<!--水平方向の開始拡大縮小倍率を設定-->
android:fromXScale="1"
<!--垂直方向の開始拡大縮小倍率を設定-->
android:fromYScale="1"
<!--水平方向の終了拡大縮小倍率を設定-->
android:toXScale="3"
<!--垂直方向の終了拡大縮小倍率を設定-->
android:toYScale="3"
<!--拡大縮小の中心水平方向の座標を設定-->
android:pivotX="50%"
<!--拡大縮小の中心垂直方向の座標を設定-->
android:pivotY="50%">

pivotX と pivotY には 3 つの設定方法があります:

  • 数字:例えば 50 は拡大縮小の中心が View の原点から 50px オフセットされることを示します
  • パーセンテージ:例えば 50% は拡大縮小の中心が View の原点から View 自身のサイズの 50% オフセットされることを示します
  • パーセンテージ p:例えば 50% p は拡大縮小の中心が View の原点から親 View のサイズの 50% オフセットされることを示します

その後、Activity 内でこの XML ファイルに対応する ScaleAnimation を取得し、それを設定したい View に設定すれば大丈夫です。具体的には以下の通りです:

private void scale(){
    ScaleAnimation scaleAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(this,R.anim.scale_anim);
    ivImage.startAnimation(scaleAnimation);
}

コードで拡大縮小アニメーションを作成:コードで拡大縮小アニメーションを作成するには、Animation のサブクラス ScaleAnimation を使用し、直接 ScaleAnimation オブジェクトを作成すれば大丈夫です。具体的には以下の通りです:

//コードで拡大縮小アニメーションを作成
private void scale(){
    ScaleAnimation scaleAnimation = new ScaleAnimation(1,3,1,3,
            Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation.setRepeatMode(Animation.REVERSE);
    scaleAnimation.setDuration(500);
    scaleAnimation.setRepeatCount(5);
    scaleAnimation.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator);
//        translateAnimation.setInterpolator(new AccelerateInterpolator());
    //...
    ivImage.startAnimation(scaleAnimation);
}

パラメータの pivotXType と pivotYType については前述の通りですので、ここでは繰り返しません。テスト効果は以下の通りです:

image

回転アニメーション (Rotate)#

回転アニメーションは View の角度を回転させるもので、XML で回転アニメーションを定義することも、コードで回転アニメーションを作成することもできます。回転アニメーションに対応する Animation のサブクラスは RotateAnimation です。

XML で回転アニメーションを定義:res/anim 内に rotate_anim.xml という XML ファイルを作成し、その中で回転アニメーションを以下のように定義します:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200"
    android:startOffset ="0"
    android:fillBefore = "true"
    android:fillAfter = "false"
    android:fillEnabled= "false"
    android:repeatMode = "reverse"
    android:repeatCount = "5"
    android:interpolator = "@android:anim/accelerate_interpolator"

    android:fromDegrees="0"
    android:toDegrees="100"
    android:pivotY="50%"
    android:pivotX="50%">
</rotate>

上記の XML ファイルは回転アニメーションファイルを定義しており、回転アニメーション特有の属性の意味は以下の通りです:

<!--アニメーション開始時の角度を設定。正数は時計回り、負数は反時計回りを示します-->
android:fromDegrees="0"
<!--アニメーション終了時の角度を設定。正数は時計回り、負数は反時計回りを示します-->
android:toDegrees="100"
<!--水平方向の回転中心点の座標を設定-->
android:pivotY="50%"
<!--垂直方向の回転中心点の座標を設定-->
android:pivotX="50%"

pivotX と pivotY の設定方法については前述の通りです。その後、Activity 内でこの XML ファイルに対応する RotateAnimation を取得し、それを設定したい View に設定すれば大丈夫です。具体的には以下の通りです:

private void rotate(){
    RotateAnimation rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(this,R.anim.rotate_anim);
    ivImage.startAnimation(rotateAnimation);   
}

コードで回転アニメーションを作成:コードで回転アニメーションを作成するには、Animation のサブクラス RotateAnimation を使用し、直接 RotateAnimation オブジェクトを作成すれば大丈夫です。具体的には以下の通りです:

//コードで回転アニメーションを作成
private void rotate(){
    RotateAnimation rotateAnimation = new RotateAnimation(0,100,
            Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    rotateAnimation.setRepeatMode(Animation.REVERSE);
    rotateAnimation.setDuration(1200);
    rotateAnimation.setRepeatCount(3);
    rotateAnimation.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator);
//        translateAnimation.setInterpolator(new AccelerateInterpolator());
    //...
    ivImage.startAnimation(rotateAnimation);
}

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

image

不透明度アニメーション (Alpha)#

不透明度アニメーションは View の不透明度を変更するもので、XML で不透明度アニメーションを定義することも、コードで不透明度アニメーションを作成することもできます。不透明度アニメーションに対応する Animation のサブクラスは AlphaAnimation です。

XML で不透明度アニメーションを定義:res/anim 内に alpha_anim.xml という XML ファイルを作成し、その中で不透明度アニメーションを以下のように定義します:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset ="0"
    android:fillBefore = "true"
    android:fillAfter = "true"
    android:fillEnabled= "false"
    android:repeatMode = "restart"
    android:repeatCount = "0"
    android:interpolator = "@android:anim/accelerate_interpolator"

    android:fromAlpha="1"
    android:toAlpha="0">
</alpha>

上記の XML ファイルは不透明度アニメーションファイルを定義しており、不透明度アニメーション特有の属性の意味は以下の通りです:

<!--アニメーションの開始不透明度を設定。0は透明、1は不透明を示します-->
android:fromAlpha="1"
<!--アニメーションの終了不透明度を設定。0は透明、1は不透明を示します-->
android:toAlpha="0"

その後、Activity 内でこの XML ファイルに対応する AlphaAnimation を取得し、それを設定したい View に設定すれば大丈夫です。具体的には以下の通りです:

private void alpha(){
    AlphaAnimation alphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this,R.anim.alpha_anim);
    ivImage.startAnimation(alphaAnimation); 
}

コードで不透明度アニメーションを作成:コードで不透明度アニメーションを作成するには、Animation のサブクラス AlphaAnimation を使用し、直接 AlphaAnimation オブジェクトを作成すれば大丈夫です。具体的には以下の通りです:

//コードで不透明度アニメーションを作成
private void alpha(){
    AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f);
    alphaAnimation.setRepeatMode(Animation.RESTART);
    alphaAnimation.setDuration(1500);
    alphaAnimation.setRepeatCount(3);
//        alphaAnimation.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator);
//        translateAnimation.setInterpolator(new AccelerateInterpolator());
    //...
    ivImage.startAnimation(alphaAnimation);
}

不透明度アニメーションのテスト効果は以下の通りです:

image

これで、移動、拡大縮小、回転、不透明度アニメーションの内容の紹介が完了しました。これらのアニメーションを単独で使用するだけでなく、組み合わせてより複雑なアニメーションを実現することもできます。

組み合わせアニメーション#

組み合わせアニメーションは AnimationSet を使用して実現できます。XML で組み合わせアニメーションを定義することも、コードで組み合わせアニメーションを作成することもできます。不透明度アニメーションに対応する Animation のサブクラスは AnimationSet です。

XML で組み合わせアニメーションを定義:res/anim 内に combine_anim.xml という XML ファイルを作成し、その中で組み合わせアニメーションを以下のように定義します:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1200">

    <!--不透明度アニメーション-->
    <alpha
        android:repeatMode="reverse"
        android:repeatCount="10"
        android:fromAlpha="1"
        android:toAlpha="0.5" />

    <!--回転アニメーション-->
    <rotate
        android:repeatMode="reverse"
        android:repeatCount="10"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />

    <!--拡大縮小アニメーション-->
    <scale
        android:repeatMode="reverse"
        android:repeatCount="10"
        android:fromXScale="1"
        android:fromYScale="1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="3"
        android:toYScale="3" />
</set>

その後、Activity 内でこの XML ファイルに対応する AnimationSet を取得し、それを設定したい View に設定すれば大丈夫です。具体的には以下の通りです:

private void combine(){
    AnimationSet animationSet = (AnimationSet) AnimationUtils.loadAnimation(this,R.anim.combine_anim);
    ivImage.startAnimation(animationSet);
}

コードで組み合わせアニメーションを作成:コードで組み合わせアニメーションを作成するには、Animation のサブクラス AnimationSet を使用し、直接 AnimationSet オブジェクトを作成し、組み合わせるアニメーションを順番に追加します。具体的には以下の通りです:

//コードで組み合わせアニメーションを作成
private void combine(){
    AnimationSet animationSet = new AnimationSet(true);
    AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.3f);
    alphaAnimation.setRepeatMode(Animation.REVERSE);
    alphaAnimation.setRepeatCount(3);
    RotateAnimation rotateAnimation = new RotateAnimation(0,360,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    rotateAnimation.setRepeatMode(Animation.REVERSE);
    rotateAnimation.setRepeatCount(3);
    ScaleAnimation scaleAnimation = new ScaleAnimation(1,3,1,3,
            Animation.RELATIVE_TO_SELF,0.5f,
            Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnimation.setRepeatMode(Animation.REVERSE);
    scaleAnimation.setRepeatCount(3);

    animationSet.addAnimation(alphaAnimation);
    animationSet.addAnimation(rotateAnimation);
    animationSet.addAnimation(scaleAnimation);

    animationSet.setDuration(1200);
    //AnimationSetはアニメーションの繰り返し再生をサポートしていません。組み合わせアニメーションを繰り返し再生したい場合は、各アニメーションの繰り返し再生を設定する必要があります。
//        animationSet.setRepeatMode(Animation.REVERSE);
//        animationSet.setRepeatCount(10);

    ivImage.startAnimation(animationSet);
}

組み合わせアニメーションのテスト効果は以下の通りです:

image

まとめ#

この記事では、Android 開発におけるフレームアニメーション (FrameAnimation) と補間アニメーション (TweenAnimation) の使用についてまとめました。次回はプロパティアニメーション (ObjectAnimator) について紹介します。

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