Can the time on a CountDownTimer be updated?

前端 未结 2 768
广开言路
广开言路 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
    

提交回复
热议问题