获取验证码的时候经常用到一个控件,就是点击按钮之后会出现60秒倒计时。
其实这个原理很简单,就是 textview 和 Timer 的混合使用
直接贴代码
public class VerificationCountDownTimer extends CountDownTimer {
private final String text;
private final TextView view;
private final static long MILLIS_IN_FUTURE=60000;//默认60秒
private final static long COUNT_DOWN_INTERVAL=1000;//1秒计时一次
/** * @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 VerificationCountDownTimer(long millisInFuture, long countDownInterval , TextView textView) {// super(countDownInterval, millisInFuture); super(MILLIS_IN_FUTURE, COUNT_DOWN_INTERVAL);
this.view = textView;
text = textView.getText().toString();
}
@Override
public void onFinish() {// 计时完毕
view.setText(text);
view.setClickable(true);
}
@Override
public void onTick(long millisUntilFinished) {
view.setClickable(false);// 防止重复点击
view.setText(millisUntilFinished / COUNT_DOWN_INTERVAL + "秒后可点击");
}
}
使用时 只需要
verificationCountDown = (TextView)findViewById(R.id.verificationCountDown);
verificationCountDown.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) { //0,0 可以自定义
new VerificationCountDownTimer(0,0,verificationCountDown);
}
});
是不是很简单,那么我们来看看 CountDownTimer源码
public synchronized final CountDownTimer start() {
mCancelled = false;
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
// SystemClock.elapsedRealtime() 返回系统启动到现在的时间
mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
mHandler.sendMessage(mHandler.obtainMessage(MSG));
//发送消息
return this;
}
在仔细看一下消息处理
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
synchronized (CountDownTimer.this) {
//如果取消事件
if (mCancelled) {
return;
}
// 计算倒数时间 持续的
final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
//到0时,自动调用finish 方法
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);
}
}
}
};
网友评论