简述:
我们再做项目的时候经常会遇到“点击获取短信验证码”、“点击获取、、、”等等,然后就开始倒计时,在Android中提供了这样的一个抽象类:CountDownTimer。
代码实现:
由于源码不多我就将其贴出来,下面是其源码
public abstract class CountDownTimer {
/**
* 总的倒计时时间
*/
private final long mMillisInFuture;
/**
* 接收onTick(long)回调的间隔时间
*/
private final long mCountdownInterval;
private long mStopTimeInFuture;
/**
* 倒计时是否取消
*/
private boolean mCancelled = false;
/**
* 构造方法
* millisInFuture:总的倒计时时间
* countDownInterval:接收onTick(long)回调的间隔时间
*/
public CountDownTimer(long millisInFuture, long countDownInterval) {
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
}
/**
* 取消倒计时的方法
*/
public synchronized final void cancel() {
mCancelled = true;
mHandler.removeMessages(MSG);
}
/**
* 开始倒计时的方法
*/
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
return this;
}
/**
* 固定间隔被调用
* millisUntilFinished:倒计时剩余时间
*/
public abstract void onTick(long millisUntilFinished);
/**
* 倒计时完毕时回调的方法
*/
public abstract void onFinish();
private static final int MSG = 1;
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) {
sendMessageDelayed(obtainMessage(MSG), millisLeft);
} else {
long lastTickStart = SystemClock.elapsedRealtime();
onTick(millisLeft);
long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
while (delay < 0) delay += mCountdownInterval;
sendMessageDelayed(obtainMessage(MSG), delay);
}
}
}
};
}
CountDownTimer的API:
在源码中我们看到CountDownTimer类中一共有4个方法:
①start():用于开启倒计时
②cancel():取消倒计时
③onTick(long millisUntilFinished):这个方法调用的次数很多次呀,每个“时间间隔”都要调用此方法。
④onFinish():倒计时结束后调用该方法
CountDownTimer的应用:
先看一下官方给出的Demo:
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
看到官方给出的Demo我们基本上了解了CountDownTimer的简单用法,在网上我还看到有人说在Android5.0以前的版本不能够很好的支持取消cancel();倒计时器。这是由于在之前源码中缺少上面贴出源码的第63,64,65,66这4行代码造成的,为了方便自己能够使用Android倒计时,我们不如自己在封装一个自己的计时器,如果大家着急用可以直接拿走即用,先看一下代码:
/**
* 倒计时的工具类
*
* @Time 2016年1月11日
* @author lizy18
*/
@SuppressWarnings("unused")
public class TinyjoyCountDownTimer extends CountDownTimer {
private Activity mActivity;
private Fragment mFragment;
private TextView btn;// 按钮触发器
private String mType;
/**
* 在Activity中触发倒计时器
*
* @param activity 调用倒计时的Activity页面
* @param millisInFuture 倒计时的总时间,单位是ms
* @param countDownInterval 回调onTick()的间隔时间
* @param btn 显示倒计时绑定的组件
*/
public TinyjoyCountDownTimer(Activity activity, long millisInFuture,
long countDownInterval, View btn, String type) {
super(millisInFuture, countDownInterval);
this.mActivity = activity;
if (btn instanceof TextView) {
this.btn = (TextView) btn;
}
this.mType = type;
}
/**
* 在Fragment中触发倒计时器
*
* @param fragment
* @param millisInFuture
* @param countDownInterval
* @param btn
*/
public TinyjoyCountDownTimer(Fragment fragment, long millisInFuture,
long countDownInterval, View btn) {
super(millisInFuture, countDownInterval);
this.mFragment = fragment;
if (btn instanceof TextView) {
this.btn = (TextView) btn;
}
}
@Override
public void onTick(long millisUntilFinished) {
/**
* 在倒计时期间将倒计时按钮设置为不可点击
*/
btn.setClickable(false);
if (millisUntilFinished / 1000 < 10) {
btn.setText("重新发送(0" + millisUntilFinished / 1000 + ")");// 设置倒计时时间
} else {
btn.setText("重新发送(" + millisUntilFinished / 1000 + ")");// 设置倒计时时间
}
// 设置按钮为灰色,这时是不能点击的
if (mType != null && mType.equals("reset")) {
btn.setTextColor(mActivity.getResources().getColor(R.color.gay));
} else {
btn.setBackgroundResource(R.drawable.shape_phonecode_bg);
// 讲倒计时时间显示为红色
btn.setTextColor(mActivity.getResources().getColor(R.color.blue));
}
}
@Override
public void onFinish() {
if (mType != null && mType.equals("reset")) {
btn.setText("点击获取验证码");
btn.setTextColor(mActivity.getResources().getColor(R.color.black));
btn.setClickable(true);// 重新获得点击
} else {
btn.setText("获取验证码");
btn.setTextColor(mActivity.getResources().getColor(R.color.white));
btn.setBackgroundColor(mActivity.getResources().getColor(
R.color.blue));
btn.setClickable(true);// 重新获得点击
btn.setBackgroundColor(mActivity.getResources().getColor(
R.color.blue));
}
}
}
至于使用那就更方便了,往下看:
Button btnGetPhoneCode = (Button) findViewById(R.id.btn_getphonecode);
TinyjoyCountDownTimer timer = new TinyjoyCountDownTimer(DownTimeActivity.this, 60000,
1000, btnGetPhoneCode, "reset");
timer.start();
完整Demo下载路径:TinyjoyCountDownTimer倒计时器源码下载