あるViewに対してアニメーション①を実行し、終了したらアニメーション②を実行し、、ということを実現したいとします。ただリスナーでアニメーションの終了を検知しているとコードがネストしたり、繰り返したい場合にどうすればいいか困ったりします。
そういう場合は、enum
でステートマシンを作ってアニメーションを実行するとコードがすっきりします。
例えば下記のコードは、あるViewに対してアニメーション AnimState1
AnimState2
AnimState3
の順次実行を繰り返し行うコードの例です。
SomeAnimState.java
enum SomeAnimState {
Stop {
@Override
protected void start(View view) {
changeState(view, AnimState1);
}
},
AnimState1 {
@Override
protected void enter(View view) {
view.setAlpha(0);
view.animate().alpha(1.0F).setDuration(1000).setInterpolator(new LinearInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
changeState(view, AnimState2);
}
});
}
},
AnimState2 {
@Override
protected void enter(View view) {
view.animate().scaleX(2.0F).scaleY(2.0F).setDuration(1000).setInterpolator(new OvershootInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
changeState(view, AnimState3);
}
});
}
},
AnimState3 {
@Override
protected void enter(View view) {
view.animate().scaleX(1.0F).scaleY(1.0F).setDuration(1500).setInterpolator(new FastOutSlowInInterpolator()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
changeState(view, AnimState1);
}
});
}
},
;
private static SomeAnimState currentState = Stop;
public static void startAnim(View view) {
currentState.start(view);
}
public static void stopAnim(View view) {
currentState.stop(view);
}
protected void start(View view) {}
@CallSuper
protected void stop(View view) {
currentState.changeState(view, Stop);
}
protected void enter(View view) {} // 各ステートが開始した際にさせる処理をオーバーライドで記述
protected void exit(View view) {} // 各ステートが終了する際にさせる処理をオーバーライドで記述
protected void changeState(View view, SomeAnimState nextState) {
if (currentState != this) return;
currentState.exit(view);
currentState = nextState;
currentState.enter(view);
}
}
アニメーションを開始する場合は、staticメソッド startAnim()
を呼び出します。すると各ステートの start()
を呼び出すようになっているので、もし Stop
ステータスでない場合は、何もしないようになっています。
アニメーションの開始
SomeAnimState.startAnim(someView);
同様に、繰り返しアニメーションにしている場合等でアニメーションを終了する場合は、staticメソッド stopAnim()
を呼び出します。
アニメーションの終了
SomeAnimState.stopAnim(someView);
繰り返しにしている/していないに関わらず、アニメーション実行中にActivityの終了等でViewが死ぬケースがあるので、
onDestroy()
できちんと終了を呼び出しておくと安全です。
以上