The CountDownTimer default Constructor takes the values millisInFuture and countDownInterval. If the user stops the timer, changes his settings to a different millisInFuture
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
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