这是一个Google 已经封装好的倒计时抽象类,在开发过程中可以快速地实现倒计时功能,如:获取手机验证码的倒计时实现;该类封装的源码和使用都比较简单。
一、源码
public abstract class CountDownTimer {
/**
* Millis since epoch when alarm should stop.
*/
private final long mMillisInFuture;
/**
* The interval in millis that the user receives callbacks
*/
private final long mCountdownInterval;
private long mStopTimeInFuture;
/**
* boolean representing if the timer was cancelled
*/
private boolean mCancelled = false;
/**
* @param millisInFuture The number of millis in the future from the call
* to {@link #start()} until the countdown is done and {@link #onFinish()}
* is called.
* @param countDownInterval The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* Cancel the countdown.
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* Callback fired on regular interval.
* @param millisUntilFinished The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
if (mCancelled) {
return;
}
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
if (millisLeft <= 0) {
onFinish();
} else if (millisLeft < mCountdownInterval) {
// no tick, just delay until done
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
// take into account user's onTick taking time to execute
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
// special case: user's onTick took more than interval to
// complete, skip to next interval
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
}
1、实现原理
通过 Handler 间隔性地发送消息来实现倒计时。
2、方法介绍:
从源码可以看到 CountDownTimer类共有5个方法,分别是:
构造方法:CountDownTimer(long,long)
取消倒计时:cancel()
开始倒计时:start()
倒计时间隔执行:onTick(long)
倒计时结束:onFinish()
(1)构造方法:CountDownTimer(long,long)
传入两个long类型的参数,第一个参数表示倒计时的总时长,第二个参数表示倒计时的间隔时间;
(2)取消倒计时方法:cancel()
方法由final关键字修饰,可被继承,不可重写;移除消息队列中的消息,倒计时停止;
(3)开始倒计时:start()
方法由final关键字修饰,可被继承,不可重写;synchronized 保证线程安全;启动Handler 开始倒计时;
(4)倒计时间隔执行:onTick(long)
抽象方法,具体实现内容由子类重写,按时间间隔执行;由 final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();看出该方法的参数为倒计时剩余时间;
(5)倒计时结束:onFinish()
抽象方法,具体实现内容由子类重写;在倒计时完成时执行;
注:handleMessage(Message msg) 中实现主要的倒计时逻辑判断。
二、简单的使用Demo
1.实现效果
倒计时中:
倒计时结束:
2.实现代码
public class MainActivity extends Activity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.btn);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CountDownTime countDown=new CountDownTime(60*1000L, 1*1000L);
countDown.start();
}
});
}
class CountDownTime extends CountDownTimer{
/*
* millisInFuture: 倒计时总时间
* countDownInterval: 间隔时间
*/
public CountDownTime(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
// 每间隔1s 执行一次
button.setText((int)(millisUntilFinished/1000)+"s");
button.setTextColor(Color.BLUE);
}
@Override
public void onFinish() {
// 倒计时结束时执行
button.setText("重新倒计时");
button.setTextColor(Color.BLACK);
cancel();
}
}
}