Can the time on a CountDownTimer be updated?

前端 未结 2 766
广开言路
广开言路 2020-12-21 14:39

The CountDownTimer default Constructor takes the values millisInFuture and countDownInterval. If the user stops the timer, changes his settings to a different millisInFuture

相关标签:
2条回答
  • 2020-12-21 15:09

    I needed it too, here's the code

    public class DynamicCountdownTimer {
    
        private CountDownTimer timer = null;
        private double negativeBias = 0.00;
        private double addingBias = 0.00;
        private int minutes = 0;
        private int ticks = 0;
        private boolean supressFinish = false;
    
        public DynamicCountdownTimer(int minutes, int ticks){
            setTimer(minutes, ticks);
        }
    
        public void updateMinutes(int minutes){
            if (timer != null){
                this.supressFinish = true;
                this.timer.cancel();
                this.timer = null;
                this.minutes = minutes;
                this.addingBias = this.negativeBias + this.addingBias;
                setTimer(this.minutes, this.ticks);
                Start();
            }
        }
    
        public void setTimer(int minutes, int ticks){
            this.minutes = minutes;
            this.ticks = ticks;
            timer = new CountDownTimer((minutes * 60 * 1000), ticks) {
                @Override
                public void onTick(long l) {
                    negativeBias = (minutes * 60 * 1000) - l;
                    long calculatedTime = l - (long)addingBias;
                    if (calculatedTime <= 0){
                        onFinish();
                    }else{
                        callback.onTick(calculatedTime);
                    }
                }
    
                @Override
                public void onFinish() {
                    if (!supressFinish){
                        callback.onFinish();
                    }
                    supressFinish = false;
                }
            };
        }
    
        public void Start(){
            if (timer != null){
                timer.start();
            }
        }
    
        public void Cancel(){
            if (timer != null){
                timer.cancel();
            }
        }
    
        public DynamicCountdownCallback callback = null;
    
        public void setDynamicCountdownCallback(DynamicCountdownCallback c){
            callback = c;
        }
    
    
        public interface DynamicCountdownCallback {
            void onTick(long l);
            void onFinish();
        }
    
    }
    

    Here is how to use it:

    DynamicCountdownTimer pCountDownTimer = null;
    
    public void initializeTimer(int minutes){
    
        pCountDownTimer = new DynamicCountdownTimer(minutes, 1000);
        pCountDownTimer.setDynamicCountdownCallback(new DynamicCountdownTimer.DynamicCountdownCallback() {
            @Override
            public void onTick(long l) {
                double progress = (double)( l) / (double)(minutes * 60 * 1000);
            }
    
            @Override
            public void onFinish() {
                // do something
            }
        });
        pCountDownTimer.Start();
    }
    

    Then you can update it like this:

    public void updateTimer(int minutes){
        pCountDownTimer.updateMinutes(minutes);
    }
    

    After updating, the timer will simply carry on. It also carries over the already passed time. This means, if the time was originally set to 30min and you update it to 45min after 10min, the remaining countdown time will be 35min.

    It does it by recreating a new Timer when the update function is called. And at onTick, the already passed time (before the update) is calculated into the new progress.

    You can change it to ms instead of min if you need it simply by replacing

    (double)(minutes * 60 * 1000) -> ms
    

    then

    int minutes -> long ms
    
    0 讨论(0)
  • 2020-12-21 15:14

    This class will not let you do much by itself.

    You can create a class that contains a CountDownTimer timer field and a method update(time, tick) that hides the implementation. You would still need to call timer.cancel() and create a new CountDownTimer with the new values. Either that, or create your countdown timer from scratch using a Handler and postDelayed(...)

    Take a look at an example of the second approach in my answer here

    0 讨论(0)
提交回复
热议问题