Android 定时/倒计时工具 - 加强版 CountDownTimer

作用

轻量级的 Android 定时/倒计时工具。

使用方法

  • start()
    开始倒计时

  • stop()
    停止倒计时

  • pause()
    暂停倒计时

  • restart()
    继续暂停的倒计时

  • onTick()
    倒计时间隔回调

  • onFinish()
    倒计时结束回调

  • CustomCountDownTimer(long millisInFuture, long countDownInterval)
    构造方法,其中参数的含义:
    millisInFuture: 总时长
    countDownInterval: 间隔时长

例如,CustomCountDownTimer(10000, 1000) 表示从现在开始倒计时,10秒后结束,每秒触发一次 onTick 事件。注意:onTick 事件在每秒的开始时刻调用,即 “onTick - 1秒“ – “onTick - 1秒“……如此重复10次。

源码

import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

/**
 * 使用 android.os.CountDownTimer 的源码
 * 1. 对回调 onTick 做了细小调整,已解决最后1秒不会倒计时到0,要等待2秒才回调 onFinish
 * 2. 添加了一些自定义方法
 * Created by iWgang on 15/10/18.
 * https://github.com/iwgang/CountdownView
 */
public abstract class CustomCountDownTimer {

    private static final long ONE_SECOND_MILLS = 1000L;
    private static final long CORRECT_OFFSET = 15L;

    private static final int MSG = 1;
    private final long mMillisInFuture;
    private final long mCountdownInterval;
    private long mStopTimeInFuture;
    private long mPauseTimeInFuture;
    private boolean isStop = false;
    private boolean isPause = false;

    /**
     * @param millisInFuture    总倒计时时间
     * @param countDownInterval 倒计时间隔时间
     */
    public CustomCountDownTimer(long millisInFuture, long countDownInterval) {
        // 解决秒数有时会一开始就减去了2秒问题(如10秒总数的,刚开始就8999,然后没有不会显示9秒,直接到8秒)
        if (countDownInterval > ONE_SECOND_MILLS) {
            millisInFuture += CORRECT_OFFSET;
        }
        mMillisInFuture = millisInFuture;
        mCountdownInterval = countDownInterval;
    }

    private synchronized CustomCountDownTimer start(long millisInFuture) {
        isStop = false;
        if (millisInFuture <= 0) {
            onFinish();
            return this;
        }
        mStopTimeInFuture = SystemClock.elapsedRealtime() + millisInFuture;
        mHandler.sendMessage(mHandler.obtainMessage(MSG));
        return this;
    }

    /**
     * 开始倒计时
     */
    public synchronized final void start() {
        start(mMillisInFuture);
    }

    /**
     * 停止倒计时
     */
    public synchronized final void stop() {
        isStop = true;
        mHandler.removeMessages(MSG);
    }

    /**
     * 暂时倒计时
     * 调用{@link #restart()}方法重新开始
     */
    public synchronized final void pause() {
        if (isStop) return;

        isPause = true;
        mPauseTimeInFuture = mStopTimeInFuture - SystemClock.elapsedRealtime();
        mHandler.removeMessages(MSG);
    }

    /**
     * 重新开始
     */
    public synchronized final void restart() {
        if (isStop || !isPause) return;

        isPause = false;
        start(mPauseTimeInFuture);
    }

    /**
     * 倒计时间隔回调
     *
     * @param millisUntilFinished 剩余毫秒数
     */
    public abstract void onTick(long millisUntilFinished);

    /**
     * 倒计时结束回调
     */
    public abstract void onFinish();


    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            synchronized (CustomCountDownTimer.this) {
                if (isStop || isPause) {
                    return;
                }

                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
                if (millisLeft <= 0) {
                    onFinish();
                }
                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);
                }
            }
        }
    };
}

你可能感兴趣的:(Android)