【问题标题】:Android: Stop AnimationDrawable after specified time, resume onResume(), pause onPause()Android:在指定时间后停止 AnimationDrawable,恢复 onResume(),暂停 onPause()
【发布时间】:2019-06-09 22:58:25
【问题描述】:

我需要在指定时间后停止AnimationDrawable,但该课程没有提供任何直接的方法来这样做。我还要求动画暂停onPause() 回调并恢复onResume() 回调。我在 StackOverflow 中找不到任何复杂的答案,所以我决定自己写下来。我希望它会帮助一些人。

【问题讨论】:

    标签: java android animationdrawable


    【解决方案1】:

    这是我的代码。

    实施:

    /**
     * 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();
            }
        }
    }
    

    用法:

    发射:

    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()回调:

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

    onResume()回调:

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

    【讨论】:

      猜你喜欢
      • 2017-11-09
      • 1970-01-01
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多