Android_验证码按钮倒计时

在注册获取验证码时候需要一个倒计时按钮。

public class MainActivity extends Activity {

TextView txt;

CountDownTimer timer = new CountDownTimer(60000, 1000) {
    
    @Override
    public void onTick(long millisUntilFinished) {
        txt.setText(millisUntilFinished/1000 + "秒");
    }
    
    @Override
    public void onFinish() {
        txt.setEnabled(true);
        txt.setText("发送验证码");
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    txt = (TextView) findViewById(R.id.txt);
    txt.setOnClickListener(new OnClickListener() {
        
        @Override
        public void onClick(View view) {
            view.setEnabled(false);
            timer.start();
        }
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    timer.cancel();
}

}

CountDownTimer

构造器、方法

public CountDownTimer (long millisInFuture, long countDownInterval)// millisInFuture 总时长, countDownInterval 时间间隔

public final synchronized void cancel () // 取消倒计时

public abstract void onFinish () // 

Callback fired when the time is up.

public abstract void onTick (long millisUntilFinished)

Callback fired on regular interval.

Parameters
millisUntilFinished
The amount of time until finished.

public final synchronized CountDownTimer start ()

源码

CountDownTimer 内部实现是通过Handler发送消息;

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;

/**
 * @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.
    取消到timer
 */
public final void cancel() {
    mHandler.removeMessages(MSG);
}

/**
 * Start the countdown.
    开始
 */
public synchronized final CountDownTimer start() {
    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) {
             // 计算剩余总时间
            final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
             // 小于等于 0 ,回调 onFinish
            if (millisLeft <= 0) {
                onFinish();
            } else if (millisLeft < mCountdownInterval) { // 小于计时间隔 ,delayed 一个消息
                // 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);
            }
        }
    }
};
}

推荐阅读更多精彩内容