简体   繁体   English

Android:在指定时间后停止AnimationDrawable,恢复onResume(),暂停onPause()

[英]Android: Stop AnimationDrawable after specified time, resume onResume(), pause onPause()

I needed to stop AnimationDrawable after the specified time, but the class doesn't provide any direct way to do so. 我需要在指定的时间后停止AnimationDrawable ,但是类没有提供任何直接的方法。 I also demanded that the animation pauses onPause() callback and resumes onResume() callback. 我还要求动画暂停onPause()回调并恢复onResume()回调。 I couldn't find any complex answer here in the StackOverflow, so I have decided to write down my own. 我在StackOverflow中找不到任何复杂的答案,所以我决定写下自己的答案。 I hope it will help some people. 我希望它会帮助一些人。

Here is my code. 这是我的代码。

Implementation: 执行:

/**
 * Adds some new features which are not available in the {@link AnimationDrawable} class.
 * The main difference is that this class allows setting a timer, which indicates for how
 * long is the animation supposed to be rendered.
 */
public class CustomAnimation
{
    //==============================================================================================
    private AnimationDrawable animation;

    //==============================================================================================
    private Drawable currentFrame;

    //==============================================================================================
    private Callable<Void> afterDelay;

    //==============================================================================================
    private long lastCheckedTime;
    private long duration;

    //==============================================================================================
    private Runnable animationFinished;
    private Handler handlerAnimation;

    //==============================================================================================
    private boolean infinite;


    /**
     * @param animation the {@link AnimationDrawable} which is about to animate
     */
    public CustomAnimation(AnimationDrawable animation)
    {
        this.animation = animation;
    }

    /**
     * Sets a time limit after which is the animation finished.
     * @param duration time in milliseconds. Set to -1 if the animation is infinite.
     */
    public void setDuration(long duration)
    {
        this.duration = duration;
        if(duration == -1) infinite = true;
    }

    /**
     * Starts the animation from the first frame, looping if necessary.
     */
    public void animate()
    {
        animation.start();
        lastCheckedTime = System.currentTimeMillis();
        stopAfterDelay();
    }

    /**
     * Cancels the animation.
     */
    public void cancel()
    {
        animation.stop();
        if(handlerAnimation != null) handlerAnimation.removeCallbacks(animationFinished);
    }

    /**
     * Pauses the animation.
     */
    public void pause()
    {
        currentFrame = animation.getCurrent();
        duration = getRemainingTime();
        animation.setVisible(false, false);
    }

    /**
     * Pauses the animation.
     * Call this method only in the onPause() callback.
     */
    public void onPause()
    {
        currentFrame = animation.getCurrent();
        duration = getRemainingTime();
        cancel();
    }

    /**
     * Resumes the animation.
     */
    public void resume()
    {
        if(!animation.isRunning())
        {
            lastCheckedTime = System.currentTimeMillis();
            animation.setVisible(true, false);
            setFrame();
            stopAfterDelay();
        }
    }

    /**
     * Resumes the animation.
     * Call this method only in the onResume() callback.
     */
    public void onResume()
    {
        if(!animation.isRunning())
        {
            lastCheckedTime = System.currentTimeMillis();
            animation.start();
            setFrame();
            stopAfterDelay();
        }
    }

    /**
     * Sets the callable method which is called right after the animation finishes.
     * @param afterDelay the callable method which returns nothing
     */
    public void setCallableAfterDelay(Callable<Void> afterDelay)
    {
        this.afterDelay = afterDelay;
    }

    /**
     * @return remaining time in milliseconds until the animation is supposed to be finished
     */
    public long getRemainingTime()
    {
        return duration - (System.currentTimeMillis() - lastCheckedTime);
    }

    private void stopAfterDelay()
    {
        if(infinite) return;

        animationFinished = new Runnable()
        {
            @Override
            public void run()
            {
                animation.stop();

                try { if(afterDelay != null) afterDelay.call(); }
                catch(Exception e) { e.printStackTrace(); }
            }
        };
        handlerAnimation = new Handler();
        handlerAnimation.postDelayed(animationFinished, duration);
    }

    private void setFrame()
    {
        for(int i = 0; i < animation.getNumberOfFrames(); i++)
        {
            Drawable checkFrame = animation.getFrame(i);
            if(checkFrame == currentFrame) break;
            animation.run();
        }
    }
}

Usage: 用法:

Launch: 发射:

CustomAnimation animation = new CustomAnimation((AnimationDrawable) img.getBackground());
animation.setDuration(5000);
animation.setCallableAfterDelay(new Callable<Void>()
{
     @Override
     public Void call()
     {
        img.setBackgroundResource(R.drawable.imgFinished);
        return null;
     }
});

animation.animate();

onPause() callback: onPause()回调:

@Override
public void onPause()
{
    super.onPause();
    animation.onPause();
}

onResume() callback: onResume()回调:

@Override
public void onResume()
{
    super.onResume();
    animation.onResume();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM