While searching for a count-down chronometer in the android API, one finds that most resembles is the CountDownTimer class; but it only starts a count-down, and send an event on every predetermined time, and one event when finish, but, what if I want to pause it? I've create a CountDownChronometer class to manage this, and one interface that must implement the class which instantiates it:
CountDownChronometer
Use the constructor to set up the count-down, start() to start it or resume it after pause(), and stop() to cancel the count-down:
package reprom.blogspot.com;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.util.Log;
/**
* @author David 'svprdga' Serrano Canales
*/
public class CountDownChronometer{
// Set here the milliseconds interval for every tick.
private long millisInterval = 500;
private final static String TAG = "CountDownChronometer";
private ICountDownChronometer handler;
private boolean isPaused = false;
private long initCountDownMillis;
private long restartCountDownMillis;
private long startCountDownMillis;
private CountDownTimerImpl countDownTimerImpl;
/**
* CountDownChronometer's public constructor.
* @param initCountDownMillis Milliseconds until the count-down ends.
* @param handler Object which invoked this constructor, with ICountDownChronometer interface implemented.
*/
public CountDownChronometer(long initCountDownMillis, ICountDownChronometer handler){
this.initCountDownMillis = initCountDownMillis;
this.handler = handler;
}
/**
* Starts the count-down. Also used for restart after pause() call.
*/
public void start(){
long countDownMillis = 0;
if (isPaused){
countDownMillis = restartCountDownMillis;
isPaused = false;
} else {
countDownMillis = initCountDownMillis;
}
countDownTimerImpl = new CountDownTimerImpl(countDownMillis);
startCountDownMillis = SystemClock.elapsedRealtime();
countDownTimerImpl.start();
}
/**
* Pauses the count-down.
*/
public void pause(){
isPaused = true;
restartCountDownMillis = initCountDownMillis - (SystemClock.elapsedRealtime() - startCountDownMillis);
initCountDownMillis = restartCountDownMillis;
Log.d("countDown", "restartCountDownMillis: "+restartCountDownMillis);
countDownTimerImpl.cancel();
}
/**
* Stops and cancels the count-down.
*/
public void stop(){
countDownTimerImpl.cancel();
countDownTimerImpl = null;
isPaused = false;
onCountDownFinish();
}
/**
* Method which is invoked on every count-down tick.
* @param millisUntilFinished
*/
public void onCountDownTick(long millisUntilFinished){
handler.onCountDownTimerTick(millisUntilFinished);
}
/**
* Method which is invoked when the count-down finishes.
*/
public void onCountDownFinish(){
handler.onCountDownTimerFinish();
}
public class CountDownTimerImpl extends CountDownTimer{
/**
* CountDownTimerImpl constructor.
* @param millisInFuture Time in milliseconds until the count-down ends.
*/
public CountDownTimerImpl(long millisInFuture) {
super(millisInFuture, millisInterval);
}
public void onTick(long millisUntilFinished) {
onCountDownTick(millisUntilFinished);
}
public void onFinish() {
onCountDownFinish();
}
}
}
ICountDownChronometer
This interface must be implemented for the objects that instantiates the CountDownChronometer, the implemented methos allows you to control the count-down tick events, and the finish event:
/**
* @author David 'svprdga' Serrano Canales
*/
public interface ICountDownChronometer {
/**
* Method called on every CountDownTimer tick.
*/
public void onCountDownTimerTick(long millisUntilFinished);
/**
* Method called when CountDownTimer finishes.
*/
public void onCountDownTimerFinish();
}