四十三、【验证码倒计时】

152 阅读1分钟

android 为我们封装好 CountDownTimer

if (null != mLoginView){
   mLoginView.verifyCodeSuccess(60,60);
}

@Override
public void verifyCodeSuccess(int reaskDuration, int expireDuration) {
    showMsg("注册短信下发,验证码 " + expireDuration / 60 + " 分钟内有效!");
    OtherUtils.startTimer(new WeakReference<TextView>(tvVerifyCode), "验证码", reaskDuration, 1);
}

/**
  * 在按钮上启动一个定时器
  * @param tvVerifyCode  验证码控件
  * @param defaultString 按钮上默认的字符串
  * @param max           失效时间(单位:s)
  * @param interval      更新间隔(单位:s)
  */
public static void startTimer(final WeakReference<TextView> tvVerifyCode,
                                  final String defaultString,
                                  int max,
                                  int interval) {
    tvVerifyCode.get().setEnabled(false);
    // 由于CountDownTimer并不是准确计时,在onTick方法调用的时候,time会有1-10ms左右的误差,这会导致最后一秒不会调用onTick()
    // 因此,设置间隔的时候,默认减去了10ms,从而减去误差。
    // 经过以上的微调,最后一秒的显示时间会由于10ms延迟的积累,导致显示时间比1s长max*10ms的时间,其他时间的显示正常,总时间正常
    new CountDownTimer(max * 1000, interval * 1000 - 10) {
        @Override
        public void onTick(long time) {
            // 第一次调用会有1-10ms的误差,因此需要+15ms,防止第一个数不显示,第二个数显示2s
            if (null == tvVerifyCode.get())
                this.cancel();
            else
                tvVerifyCode.get().setText("" + ((time + 15) / 1000) + "s");
        }
        @Override
        public void onFinish() {
            if (null == tvVerifyCode.get()) {
                this.cancel();
                return;
            }
            tvVerifyCode.get().setEnabled(true);
            tvVerifyCode.get().setText(defaultString);
        }
    }.start();
}