1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AnimationDrawableでアニメーションの完了を検知

Posted at

フレームアニメーションの完了が検知できない

「アニメーションの終了を待ってから何か処理を行いたい」という状況はよくあると思うのですが、どうやら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();

これで一応目的は達成できたから良いのだけど、継承した場合に動かない理由が分からないのはちょっと気持ち悪いかも。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?