android中的倒计时功能的实现

1,122 阅读2分钟

在app中经常会遇到要实现倒计时功能。因为安卓框架自带倒计时功能,所以可以不用自己手写Handler去实现。

android.os中有叫CountDownTimer的抽象类。可以继承该类,重写fun onTick(millisUntilFinished: Long)fun onFinish()即可。


如果仔细探究CountDownTimer的源码,它的实现是方式用的是Handler。 源码如下:

 // handles counting down
    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            synchronized (CountDownTimer.this) {
                if (mCancelled) {
                    return;
                }
                // 计算剩余时间
                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
                // 如果剩余实现小于等于0, 则结束当前的handler
                if (millisLeft <= 0) {
                    onFinish();
                } else {
                    // 调用用法方法开始的时间
                    long lastTickStart = SystemClock.elapsedRealtime();
                    // 把剩余时间当作参数,调用onTick方法
                    onTick(millisLeft);

                    // 为了防止执行用户的代码会产生延迟, 所以记录执行用户方法所需要的时间
                    // take into account user's onTick taking time to execute
                    long lastTickDuration = SystemClock.elapsedRealtime() - lastTickStart;
                    long delay;

                    // 如果剩余时间小于倒计时间隔
                    if (millisLeft < mCountdownInterval) {
                        // just delay until done
                        // 计算延迟
                        delay = millisLeft - lastTickDuration;

                        // special case: user's onTick took more than interval to
                        // complete, trigger onFinish without delay
                        if (delay < 0) delay = 0;
                    } else {
                        delay = mCountdownInterval - lastTickDuration;

                        // special case: user's onTick took more than interval to
                        // complete, skip to next interval
                        while (delay < 0) delay += mCountdownInterval;
                    }

                    sendMessageDelayed(obtainMessage(MSG), delay);
                }
            }
        }
    };

CountDownTimer(millisInFuture, countDownInterval): CountDownTimer的构造方法。第一个参数时想要计时的时间,第二个参数时计时间隔,比如1S。注意:这里所有参数的单位都是毫秒(1秒=1000毫秒)

fun onTick(millisUntilFinished: Long): 是计时过程中调用的方法,比如更新UI等等。

fun onFinish(): 是当计时结束时调用的方法。


如果想要把毫秒和转换成秒和分, 则可以使用TimeUnit类可以快速实现。 比如想把毫秒换成秒,则可以TimeUnitTimeUnit.MILLISECONDS.toSeconds(milliseconds)来完成。


所以整体倒计时的实现方法时如下:

class CountDown(
        millisInFuture: Long,
        countDownInterval: Long
    ) : CountDownTimer(millisInFuture, countDownInterval) {
        @SuppressLint("SetTextI18n")
        override fun onTick(millisUntilFinished: Long) {
            val minutes = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)
            val seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60

            // 转换成2位数字
            val minutesStr = String.format("%02d", minutes)
            val secondsStr = String.format("%02d", seconds)
            // 转换成表示时间的格式
            _leftTime.value = "$minutesStr:$secondsStr"
        }

        override fun onFinish() {
            //TODO : 在这里实现倒计时结束时的功能
        }
    }

最后实例化CountDown类,并调用start()方法来开始倒计时。

val countDown = CountDown(10000,1000)
count.start()

取消倒计时调用count.cancel()来取消。