按照惯例是先看看效果
去年我也写过实现倒计时功能的博客,当时用的是Timer类,代码相对来说还比较多,今天用到的这个类似系统封装好的倒计时类,实现起来比较简单,源码也简单易懂,具体实现代码
//拿到countDownTimer对象,参数1:一共多少毫秒,参数2:间隔多少毫秒
CountDownTimer countDownTimer = new CountDownTimer(10000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
//让按钮不能被点击
button.setEnabled(false);
//设置显示倒计时时间
button.setText(millisUntilFinished/1000+"秒");
}
@Override
public void onFinish() {
//倒计时结束之后恢复text显示
button.setText("开始倒计时");
//让按钮重新可以点击
button.setEnabled(true);
}
};
//开始倒计时
countDownTimer.start();
一共2个步骤
1,new 一个countDownTimer对象
2,调用start()方法开始倒计时
是不是很简单,下面看看源码是怎么实现的
public abstract class CountDownTimer {
//剩余的总时间, 单位毫秒.
private final long mMillisInFuture;
//间隔时间, 单位毫秒.
private final long mCountdownInterval;
//停止时的时间
private long mStopTimeInFuture;
//是否取消倒计时
private boolean mCancelled = false;
//构造方法,传入一个总时间,和间隔时间
public CountDownTimer(long millisInFuture,
long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
//取消倒计时
public synchronized final void cancel() {
mCancelled = true;//取消倒计时赋值为trun
mHandler.removeMessages(MSG);//一出消息
}
//开始倒计时的方法
public synchronized final CountDownTimer start() {
mCancelled = false;//取消倒计时赋值为false,处于倒计时状态
if (mMillisInFuture <= 0) {//如果传入的总时间小于0直接结束并返回
onFinish();
return this;
}
//SystemClock.elapsedRealtime():
//返回系统启动到现在的毫秒数,包含休眠时间。
mStopTimeInFuture = SystemClock.elapsedRealtime()
+ mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
//当前任务每完成一次倒计时间隔时间时回调
public abstract void onTick(long millisUntilFinished);
//当前任务完成的时候回调
public abstract void onFinish();
//MSG
private static final int MSG = 1;
//主要是处理对 millisLeft 剩余时间的判断,
//其中 delay 的处理需要注意,当 onTick() 方法耗时过长会进行跳过
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) {//如果运行时间小于等于0,结束倒计时
onFinish();
} else if (millisLeft < mCountdownInterval) {//剩余时间小于间隔时间
// no tick, just delay until done
//发送剩余时间数
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
//获取启动到现在的毫秒数
long lastTickStart = SystemClock.elapsedRealtime();
//回调 onTick()
onTick(millisLeft);
long delay = lastTickStart
+ mCountdownInterval - SystemClock.elapsedRealtime();
while (delay < 0) delay += mCountdownInterval;
//发送延迟时间
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
}
可以看到他也是用的handler来实现倒计时,间隔时间发送消息来实现的