【Android】アニメーションの同時実行や制御、イベント検知方法

JUnitについての書籍が遂に発売します!
Java開発時のユニットテストを加速する「JUnit速効レシピ」


Androidアプリ開発において、多岐にわたって使用するアニメーションの実装方法や
細かい制御、開始や終了等のイベント検知の方法等をソースコード付きで解説します。

主に、android.view.animationパッケージの
Animationクラスを基底とした四つの基本的なアニメーションクラスを元に
アニメーションの合成や同時実行についても触れ、
それぞれのアニメーションの作成方法や動き、引数の内容も交えて
解説していきます。


まずは、『透明度』『位置』『角度』『大きさ』を変更する
基本的なアニメーションクラスの解説から、それぞれに指定する事の出来るオプション値の解説、
アニメーション実行時に検知する事の出来るイベントのリスナー作成といった流れで
見ていきましょう。


  1. フェードイン・フェードアウトを可能にするAlphaAnimation
  2. 移動アニメーションをつかさどるTranslateAnimation
  3. 回転動作を可能にするRotateAnimation
  4. 拡大・縮小等のサイズ変更を可能にするScaleAnimation
  5. 基本的なアニメーションを合成して複雑なアニメーションを実現するAnimationSet
  6. アニメーションを繰り返し実行しよう
  7. アニメーションの実行をキャンセルしよう
  8. 次のアニメーションまでの実行時間を指定する
  9. アニメーション後の状態を指定しよう
  10. アニメーションの開始や終了を検知して特定の処理を行う


フェードイン・フェードアウトを可能にするAlphaAnimation




AlphaAnimationでは、アニメーション開始時と終了時の透明度を指定する事で、
簡単にフェードイン・フェードアウトを実行する事が出来ます。

まず、AlphaAnimationをnewします。その時に与えるコンストラクタの引数として
第一引数がアニメーション開始時の透明度、そして第二引数がアニメーション終了時の透明度です。

// 透明にするアニメーションを作成
// new AlphaAnimation( アニメーション開始前透明度, アニメーション終了時透明度);
AlphaAnimation animation_alpha = new AlphaAnimation( 1, 0 );


そして、アニメーションにかける時間を指定する事も可能です。
時間を指定する場合は、『setDuration()』を使用しましょう。
引数に、ミリセック単位にてアニメーション実行時間を指定します。

// アニメーション実行時間を指定する(ms)
animation_alpha.setDuration( 500 );


アニメーションの実行は、ターゲットとなるviewに対して、
『startAnimation()』を起動させ、引数に作成したアニメーションを渡す事で実行されます。


上記の処理を纏めると、下記の様な実装になるかと思います。




// 透明にするアニメーションを作成
AlphaAnimation animation_alpha = new AlphaAnimation( 1, 0 );

// アニメーション実行時間を指定する(ms)
animation_alpha.setDuration( 500 );

// アニメーションの起動
this.targetView.startAnimation( animation_alpha );







移動アニメーションをつかさどるTranslateAnimation




TranslateAnimationでは、viewの移動アニメーションを作成します。
TranslateAnimation作成時のコンストラクタへ渡す引数は、
第一引数にアニメーション開始時のX座標。
第二引数にアニメーション終了時のX座標。
第三引数にアニメーション開始時のY座標。
第四引数にアニメーション終了時のY座標。
を指定します。


// 移動するアニメーションを作成
// new TranslateAnimation( fromX, toX, fromY, toY );
TranslateAnimation animation_translate = new TranslateAnimation( 0, -320, 0, 0 ); 


アニメーション開始位置からアニメーション終了位置までの
移動にかける時間は、『setDuration()』にてミリセック単位にて指定します。

// アニメーション実行時間を指定する(ms)
animation_translate.setDuration( 500 );


アニメーションの実行方法も、前述のAlphaAnimationの時と同じで、
ターゲットとなるviewに対して『startAnimation()』で作成したアニメーションを渡す事で
実行させます。


// アニメーションの起動
this.targetView.startAnimation( animation_translate );




纏めてみますと、本当にAlphaAnimationと同じ使い方が出来て
分かりやすい事が実感できるかと思います。




// 移動するアニメーションを作成
// new TranslateAnimation( fromX, toX, fromY, toY );
TranslateAnimation animation_translate = new TranslateAnimation( 0, -320, 0, 0 ); 

// アニメーション実行時間を指定する(ms)
animation_translate.setDuration( 500 );

// アニメーションの起動
this.targetView.startAnimation( animation_translate );





回転動作を可能にするRotateAnimation




RotateAnimationはviewの角度を変える事で
回転系のアニメーションを作成する事が出来ます。

RotateAnimation作成時のコンストラクタには
第一引数として、アニメーション開始時の角度。
第二引数としてアニメーション終了時の角度。
第三引数として、回転の軸となる位置のX座標、
第四引数として、回転の軸となる位置のY座標
を指定します
(第三引数と第四引数で指定した中心位置を基準にして第一引数の角度から第二引数の角度まで回転します)



// 回転するアニメーションを作成
// new RotateAnimation( 開始角度, 終了角度, X軸, Y軸 );
RotateAnimation animation_rotate = new RotateAnimation(0, 360, this.targetView.getWidth()/2, this.targetView.getHeight()/2);



上記の例では、0度から360度まで回転しますので、ちょうど一回転するアニメーションになります。
回転の中心地点となる軸は、X座標もY座標もアニメーション対象のちょうど半分の位置を指定していますので、
対象の中心を軸に360度回転するアニメーションを定義した事になります。

回転にかける時間は、これまでと同じように『setDuration()』で指定して、
対象のviewの『startAnimation();』で作成したアニメーションを渡す事で実行されます




// 回転するアニメーションを作成
// new RotateAnimation( 開始角度, 終了角度, X軸, Y軸 );
RotateAnimation animation_rotate = new RotateAnimation(0, 360, this.targetView.getWidth()/2, this.targetView.getHeight()/2);

// アニメーション実行時間を指定する(ms)
animation_rotate.setDuration( 500 );

// アニメーションの起動
this.targetView.startAnimation( animation_rotate );





拡大・縮小等のサイズ変更を可能にするScaleAnimation




ScaleAnimationは、対象の大きさを変更するアニメーションを実現するクラスです。
第一引数に、アニメーション開始時の横幅の倍率を指定します。
第二引数に、アニメーション終了時の横幅の倍率を指定します。
第三引数に、アニメーション開始時の縦幅の倍率を指定します。
第四引数に、アニメーション終了時の縦幅の倍率を指定します。



// 縮小するアニメーションを作成
// new ScaleAnimation( 開始横幅, 終了横幅, 開始縦幅, 終了横幅 );
ScaleAnimation animation_scale = new ScaleAnimation(1, 0.5f, 1, 0.5f);


横幅も縦幅も現状のサイズ『1倍』とし、アニメーション終了後のサイズを現状の半分のサイズ『0.5倍』で指定しましたので、
対象が半分のサイズへ縮小するアニメーションを作成した事になります。

ここに、アニメーションの実行時間を指定して、
これまでの様に作成したアニメーションを対象へセットします



// 縮小するアニメーションを作成
// new ScaleAnimation( 開始横幅, 終了横幅, 開始縦幅, 終了横幅 );
ScaleAnimation animation_scale = new ScaleAnimation(1, 0.5f, 1, 0.5f);

// アニメーション実行時間を指定する(ms)
animation_scale.setDuration( 500 );

// アニメーションの起動
this.targetView.startAnimation( animation_scale );





基本的なアニメーションを合成して複雑なアニメーションを実現するAnimationSet




これまで解説してきました基本的なアニメーションは合成して同時実行する事が可能です。
例えば、透明度を変化させるアニメーションクラス『AlphaAnimation』と
位置を変化させ、viewを移動させるアニメーションクラス『TranslateAnimation』を
合成して同時実行すると
『移動しながら消える』アニメーションを作成、実行する事が出来ます。

アニメーションの合成には『AnimationSet』を使用します。

第一引数には、アニメーションの状態を調整するInterpolatorを適用するか否かを
BOOL値にて指定します。


// AnimationSetを使いアニメーションを設定
AnimationSet animation_set = new AnimationSet( false );


作成した『AnimationSet』へ、合成するアニメーションを登録していきます。
登録するには『addAnimation()』へ引数として作成したアニメーションを指定します。
『addAnimation()』は『追加』という処理になりますので、
複数の登録を行う場合はそれぞれのアニメーション毎に『addAnimation()』へ
作成したアニメーションを渡して下さい。


後は、通常のアニメーションと同じように
ターゲットとなるviewに対して『startAnimation()』で
作成した『AnimationSet』を渡す事で、『addAnimation()』で登録したアニメーションが
合成され、同時に実行されます。



// 透明にするアニメーションを作成
AlphaAnimation animation_alpha = new AlphaAnimation( 1, 0 );
animation_alpha.setDuration( 500 );

// 移動するアニメーションを作成
TranslateAnimation animation_translate = new TranslateAnimation( 0, -320, 0, 0 );
animation_translate.setDuration( 500 ); // 1000msかけてアニメーションする

// AnimationSetを使いアニメーションを合成する
AnimationSet animation_set = new AnimationSet( false );
animation_set.addAnimation( animation_alpha );
animation_set.addAnimation( animation_translate );


// アニメーションの起動
// 左へ移動しながら消えるアニメーション(移動と透過の同時実行)
this.targetView.startAnimation( animation_set );




アニメーションを繰り返し実行しよう




これまで作成したアニメーションの実行回数を指定する事が出来ます。
例えば、フェードイン・フェードアウトを一回だけするのではなくて、
何回か行い、点滅の様に見せたい時や、移動を無限に行い、
画面を行ったり来たりするアニメーションを作りたい時に使用します。

アニメーションの実行回数を制御するには、実行時間を指定するやり方と同じで、
専用のメソッドが用意されています。

作成したアニメーションに対して『setRepeatCount()』にて、引数に繰り返し回数を指定します。
アニメーションの実行回数を指定するのではなく、繰り返し回数を指定します。
(1を指定した場合は「一回繰り返す」という事になり、アニメーションは二回行われます)


// アニメーションが二回繰り返され、合計三回のアニメーションが実行される
animation_alpha.setRepeatCount( 2 );


アニメーションを有限回数ではなく、無限に繰り返したい時もあるかと思います。
そういう時の為に、無限回数を指定する為の専用の定数『Animation.INFINITE』が用意されています。
無限にアニメーションを繰り返したい時は、繰り返し回数を指定する箇所に『Animation.INFINITE』を渡しましょう。


// アニメーションが無限に繰り返される
animation_alpha.setRepeatCount( Animation.INFINITE );



また、アニメーションの繰り返し方も指定する事が出来ます。
同じアニメーションを繰り返すのか?アニメーションを逆再生する様に戻して反復処理とするのか?
等を指定する事が出来ます。

指定するには『setRepeatMode()』を使用します。
繰り返し方法には専用の定数が用意されており、
単純に同じアニメーションを実行するのであれば、引数に『Animation.RESTART』を指定します。
逆再生の様に、反復したアニメーションを実行した場合は、引数に『Animation.REVERSE』を指定します。


// アニメーションが反復繰り返しとなる
animation_alpha.setRepeatMode( Animation.REVERSE );




アニメーションの実行をキャンセルしよう




繰り返しアニメーションを使用していると、途中でアニメーションを止めたくなる時もあります。
その場合に使用するのが『cancel()』メソッドです。

使い方は、作成したアニメーションのインスタンスに対して『cancel()』を実行します。

すると、次の繰り返しが行われないようにキャンセルする事が出来ます。
『次の実行をキャンセルする』というのがポイントで、
『アニメーションを途中停止する』とは違う事に注意して下さい。

なので、例えば縮小中に、途中のサイズのまま停止させるという事は出来ません。
縮小アニメーションが終わった後に、次のアニメーションが繰り返されないといった動きになります。


// アニメーションの繰り返しをキャンセルする
animation_alpha.cancel();




次のアニメーションまでの実行時間を指定する




アニメーションを繰り返す時、次のアニメーションまで隙間の時間を設けたい時もあります。
そんな時に使用するのが、『setStartOffset()』です。

アニメーションの実行までのオフセットをミリ秒にて指定します。
仮に繰り返さなくても、一番初めのアニメーションも指定した分だけ遅延して実行されるので
注意して下さい。

繰り返すのに『間』をおきたい時はとても便利ですので、効果的に使用しましょう。


// アニメーションの実行が開始されるまでの期間を指定する(ms)
animation_alpha.setStartOffset( 3000 );




アニメーション後の状態を指定しよう




例えば、縮小アニメーション後は、縮小した状態のままにしておきたい。
逆に、縮小アニメーション後は元のサイズに戻したい。
繰り返す度にそれらの指定を実行したいといった時に指定するメソッドがそれぞれ用意されています。


アニメーション実行後は元の状態に戻したい場合は、『fillBefore()』へ『true』を渡します。
アニメーション実行後も、その状態を維持したい場合は『fillAfter()』へ『true』を渡します。
アニメーションを繰り返す度に上記の指定を初期状態として適用させたい場合は、『fillEnabled()』へ『true』を渡します。


// アニメーション後は元の状態に戻す
animation_alpha.fillBefore( true );

// アニメーション後も状態を維持する
animation_alpha.fillAfter( true );

// 繰り返し時の初期状態を上記として適用する
animation_alpha.fillEnabled( true );





アニメーションの開始や終了を検知して特定の処理を行う




アニメーションの状態検知を行い時に使用するのが『AnimationListener』クラスです。
『AnimationListener』クラスには、必ず実装しなければならないメソッドが三つあり、
アニメーションに対して登録すると、アニメーションの状態イベントの通知先として
アニメーション開始時に呼ばれる『onAnimationStart()』、
アニメーション繰り返し時に呼ばれる『onAnimationRepeat()』、
アニメーション終了時に呼ばれる『onAnimationEnd()』、
の三つをオーバーライドするよう義務付けられています。

それぞれの引数には該当のアニメーションが渡されてきます。

アニメーションに対して、イベント通知クラスとなるリスナー『AnimationListener』を
登録するには『setAnimationListener()』を使用し、
内部でクラス定義まで行えるので、イベント状態による処理を
アニメーション定義と同時に行えるので可読性が高まり、とても便利です。

下記に実装例を示します。



// 透明にするアニメーションを作成
AlphaAnimation animation_alpha = new AlphaAnimation( 1, 0 );
animation_alpha.setDuration( 3000 );

// アニメーションが無限に繰り返される
animation_alpha.setRepeatCount( Animation.INFINITE );

// アニメーションが反復繰り返しとなる
animation_alpha.setRepeatMode( Animation.REVERSE );

// アニメーションリスナの登録
animation_alpha.setAnimationListener(new Animation.AnimationListener(){
 @Override
 public void onAnimationStart( Animation animation )
 {
  // アニメーションの開始時に呼ばれます
 }
 @Override
 public void onAnimationRepeat( Animation animation )
 {
  // アニメーションの繰り返し時に呼ばれます。
 }
 @Override
 public void onAnimationEnd( Animation animation )
 {
  // アニメーションの終了時に呼ばれます
 }
);

// アニメーションの起動
this.targetView.startAnimation( animation_alpha );








こういったアニメーションをサポートする基本的なクラスが整備されていてると、
Android開発がとても簡単にカッコいい仕上がりになりますね。

アニメーションは目を引きますし、注目を集めるユーザーインターフェースには必須ですので、
是非とも感覚的にとらえて、どんどんアプリに実装していって下さい。






JUnitについての書籍が遂に発売します!
Java開発時のユニットテストを加速する「JUnit速効レシピ」

コメントをお待ちしています

人気の投稿

Category

Algorithm (2) Android (8) ASP/aspx (1) Blogger (2) C/C++ (1) Chrome (5) CSS (9) Firefox (4) Fortran (1) Google (9) GoogleMap (2) HTML (12) IE (3) Information (4) iOS (2) iPhone/iPad/iPod (2) Java (6) JavaScript (16) jQuery (9) JSP (1) LifeRecipe (5) Linux (2) Macintosh (2) MapKit (4) Marketing (7) MySQL (3) NAMAZU (2) Objective-C (7) Other (7) Perl (1) PHP (9) Python (1) RSS/Atom (2) Ruby (1) Safari (2) SEO (11) Smarty (2) SQL (2) Tex (1) Three.js (1) Twitter (1) TwitterLog (313) UIKit (5) Unix (1) VBA/VBS (1) Windows (5) WordPress (3) Writing (5) XAMPP (1) XML (1) Yahoo (2) ZendFramework2 (14)

Archives