フレームアニメーションの完了が検知できない
「アニメーションの終了を待ってから何か処理を行いたい」という状況はよくあると思うのですが、どうやらAndroidのフレームアニメーション(AnimationDrawable)ではアニメーションの完了が検知できないようです。
なにか良い方法はないものかと探していたらこちらのエントリを発見。
アニメーションの完了が分かるAnimationDrawer
で、そのまま使ってみたのですが。。。
なぜかアニメーションが1フレーム目しか表示されない(完了検知して処理を実行するという部分は問題なく動く)という謎の現象に遭遇。
その原因がなんなのかは分からず仕舞いのままですが、力技で解決しました。
継承するのがダメっぽいのでラップした
なにも小細工していないAnimationDrawableだけだとアニメーションはちゃんと動くけれど、作成したサブクラスを使うとアニメーションが動かないようなので、アニメーションはAnimationDrawableに任せてリスナーも登録出来るようにラップしてみました。
AnimationDrawableEx.java
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
public class AnimationDrawableEx {
private AnimationDrawable mDrawable;
private OnAnimationStateListener mListener;
private Handler mHandler;
public AnimationDrawableEx(AnimationDrawable drawable) {
mDrawable = drawable;
mHandler = new Handler();
}
public void setOnAnimationStateListener(OnAnimationStateListener listener){
mListener = listener;
}
public boolean isRunning() {
return mDrawable.isRunning();
}
public void stop() {
mDrawable.stop();
}
public void start() {
mDrawable.start();
if(mListener != null) {
mHandler.postDelayed(new Runnable() {
public void run() {
mListener.onAnimationEnd();
}
}, getTotalDuration());
}
}
public int getTotalDuration() {
int duration = 0;
for (int i = 0; i < mDrawable.getNumberOfFrames(); i++) {
duration += mDrawable.getDuration(i);
}
return duration;
}
public interface OnAnimationStateListener {
public void onAnimationEnd();
}
}
呼び出すほうは上記エントリと一緒。
Activity.java
AnimationDrawableEx frameAnimation = new AnimationDrawableEx((AnimationDrawable) img.getBackground());
frameAnimation.setOnAnimationStateListener(new AnimationDrawableEx.OnAnimationStateListener() {
@Override
public void onAnimationEnd() {
// アニメーション終了時の処理
}
});
if (frameAnimation.isRunning()) {
frameAnimation.stop();
}
frameAnimation.start();
これで一応目的は達成できたから良いのだけど、継承した場合に動かない理由が分からないのはちょっと気持ち悪いかも。