为了账号安全,请及时绑定邮箱和手机立即绑定

Android AnimationDrawable并知道动画何时结束

Android AnimationDrawable并知道动画何时结束

沧海一幻觉 2019-12-13 15:10:52
我想用几个图像文件制作一个动画,为此,AnimationDrawable效果很好。但是,我需要知道动画何时开始以及何时结束(即添加诸如Animation.AnimationListener之类的侦听器)。搜索答案后,我很难过AnimationDrawable不支持侦听器。有谁知道如何在Android上使用侦听器创建逐帧图像动画?
查看完整描述

3 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

我需要知道一次完成的AnimationDrawable何时完成,而不必将AnimationDrawable子类化,因为我必须以XML设置动画列表。我写了这个课,并在Gingerbread和ICS上进行了测试。它可以很容易地扩展以在每个帧上提供回调。


/**

 * Provides a callback when a non-looping {@link AnimationDrawable} completes its animation sequence. More precisely,

 * {@link #onAnimationComplete()} is triggered when {@link View#invalidateDrawable(Drawable)} has been called on the

 * last frame.

 * 

 * @author Benedict Lau

 */

public abstract class AnimationDrawableCallback implements Callback {


    /**

     * The last frame of {@link Drawable} in the {@link AnimationDrawable}.

     */

    private Drawable mLastFrame;


    /**

     * The client's {@link Callback} implementation. All calls are proxied to this wrapped {@link Callback}

     * implementation after intercepting the events we need.

     */

    private Callback mWrappedCallback;


    /**

     * Flag to ensure that {@link #onAnimationComplete()} is called only once, since

     * {@link #invalidateDrawable(Drawable)} may be called multiple times.

     */

    private boolean mIsCallbackTriggered = false;


    /**

     * 

     * @param animationDrawable

     *            the {@link AnimationDrawable}.

     * @param callback

     *            the client's {@link Callback} implementation. This is usually the {@link View} the has the

     *            {@link AnimationDrawable} as background.

     */

    public AnimationDrawableCallback(AnimationDrawable animationDrawable, Callback callback) {

        mLastFrame = animationDrawable.getFrame(animationDrawable.getNumberOfFrames() - 1);

        mWrappedCallback = callback;

    }


    @Override

    public void invalidateDrawable(Drawable who) {

        if (mWrappedCallback != null) {

            mWrappedCallback.invalidateDrawable(who);

        }


        if (!mIsCallbackTriggered && mLastFrame != null && mLastFrame.equals(who.getCurrent())) {

            mIsCallbackTriggered = true;

            onAnimationComplete();

        }

    }


    @Override

    public void scheduleDrawable(Drawable who, Runnable what, long when) {

        if (mWrappedCallback != null) {

            mWrappedCallback.scheduleDrawable(who, what, when);

        }

    }


    @Override

    public void unscheduleDrawable(Drawable who, Runnable what) {

        if (mWrappedCallback != null) {

            mWrappedCallback.unscheduleDrawable(who, what);

        }

    }


    //

    // Public methods.

    //


    /**

     * Callback triggered when {@link View#invalidateDrawable(Drawable)} has been called on the last frame, which marks

     * the end of a non-looping animation sequence.

     */

    public abstract void onAnimationComplete();

}

这是使用方法。


AnimationDrawable countdownAnimation = (AnimationDrawable) mStartButton.getBackground();

countdownAnimation.setCallback(new AnimationDrawableCallback(countdownAnimation, mStartButton) {

    @Override

    public void onAnimationComplete() {

        // TODO Do something.

    }

});

countdownAnimation.start();



查看完整回答
反对 回复 2019-12-14
?
当年话下

TA贡献1890条经验 获得超9个赞

通过重写AnimationDrawable类中的selectDrawable方法,可以轻松跟踪动画结束。完整的代码如下:


public class AnimationDrawable2 extends AnimationDrawable

{

    public interface IAnimationFinishListener

    {

        void onAnimationFinished();

    }


    private boolean finished = false;

    private IAnimationFinishListener animationFinishListener;


    public IAnimationFinishListener getAnimationFinishListener()

    {

        return animationFinishListener;

    }


    public void setAnimationFinishListener(IAnimationFinishListener animationFinishListener)

    {

        this.animationFinishListener = animationFinishListener;

    }


    @Override

    public boolean selectDrawable(int idx)

    {

        boolean ret = super.selectDrawable(idx);


        if ((idx != 0) && (idx == getNumberOfFrames() - 1))

        {

            if (!finished)

            {

                finished = true;

                if (animationFinishListener != null) animationFinishListener.onAnimationFinished();

            }

        }


        return ret;

    }

}



查看完整回答
反对 回复 2019-12-14
  • 3 回答
  • 0 关注
  • 380 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信