倒計時控件 CountDownTimer 用法和原理分析
作者:Android開發(fā)編程
關于倒計時,有很多種寫法,今天我們介紹一種Android自帶的倒計時控件CountDownTimer。
本文轉載自微信公眾號「Android開發(fā)編程」,作者Android開發(fā)編程。轉載本文請聯(lián)系Android開發(fā)編程公眾號。
前言
關于倒計時,有很多種寫法,今天我們介紹一種Android自帶的倒計時控件CountDownTimer
一、CountDownTimer詳解
CountDownTimer:定時執(zhí)行在一段時間后停止的倒計時,在倒計時執(zhí)行過程中會在固定間隔時間得到通知;
1、初始化和啟動倒計時
- public CountTimer(long millisInFuture, long countDownInterval) {
- super(millisInFuture, countDownInterval);
- }
- @Override
- public void initData() {
- countDownTimer = new CountDownTimer(200000, 1000) {
- @Override
- public void onTick(long millisUntilFinished) {
- //單位天
- long day = millisUntilFinished / (1000 * 24 * 60 * 60);
- //單位時
- long hour = (millisUntilFinished - day * (1000 * 24 * 60 * 60)) / (1000 * 60 * 60);
- //單位分
- long minute = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60)) / (1000 * 60);
- //單位秒
- long second = (millisUntilFinished - day * (1000 * 24 * 60 * 60) - hour * (1000 * 60 * 60) - minute * (1000 * 60)) / 1000;
- }
- /**
- *倒計時結束后調(diào)用的
- */
- @Override
- public void onFinish() {
- }
- };
- countDownTimer.start();
- }
- /**
- * 記得關閉,負責內(nèi)存溢出
- */
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (countDownTimer != null) {
- countDownTimer.cancel();
- countDownTimer = null;
- }
- }
2、參數(shù)和方法介紹
初始化參數(shù)
- millisInFuture 從開始調(diào)用start()到倒計時完成并onFinish()方法被調(diào)用的毫秒數(shù)(倒計時時間,單位毫秒);
- countDownInterval 接收onTick(long)回調(diào)的間隔時間;
方法
- public final void cancel ()取消倒計時(取消后,再次啟動會重新開始倒計時);
- public abstract void onFinish ()倒計時完成時被調(diào)用;
- public abstract void onTick (long millisUntilFinished)固定間隔被調(diào)用;
- 參數(shù) millisUntilFinished 倒計時剩余時間;
- public synchronized final CountDownTimer start ()啟動倒計時;
二、源碼注解
- import android.os.Handler;
- import android.os.Message;
- import android.os.SystemClock;
- /**
- * Schedule a countdown until a time in the future, with
- * regular notifications on intervals along the way.
- *官方文檔中的使用例子:
- * Example of showing a 30 second countdown in a text field:
- *
- * <pre class="prettyprint">
- * new CountDownTimer(30000, 1000) {
- *
- * public void onTick(long millisUntilFinished) {
- * mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
- * }
- *
- * public void onFinish() {
- * mTextField.setText("done!");
- * }
- * }.start();
- * </pre>
- *
- * The calls to {@link #onTick(long)} are synchronized to this object so that
- * one call to {@link #onTick(long)} won't ever occur before the previous
- * callback is complete. This is only relevant when the implementation of
- * {@link #onTick(long)} takes an amount of time to execute that is significant
- * compared to the countdown interval.
- */
- /**
- * customize from CountDownTimer
- * Created by zhubingning on 16/09/16.
- */
- public abstract class CustomCountDownTimer {
- /**
- * Millis since epoch when alarm should stop.
- */
- private final long mMillisInFuture;
- //!add,為了暫停時保存當前還剩下的毫秒數(shù)
- private long mCurrentMillisLeft;
- /**
- * The interval in millis that the user receives callbacks
- */
- private final long mCountdownInterval;
- private long mStopTimeInFuture;
- /**
- * boolean representing if the timer was cancelled
- */
- private boolean mCancelled = false;
- /**
- * @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.
- */
- //構造函數(shù),(總倒計時毫秒為單位,倒計時間隔)
- public CustomCountDownTimer(long millisInFuture, long countDownInterval) {
- mMillisInFuture = millisInFuture;
- mCountdownInterval = countDownInterval;
- }
- //!add, 獲取此時倒計時的總時間
- public long getCountTimes(){
- return mMillisInFuture;
- }
- /**
- * Cancel the countdown.
- */
- //取消倒計時,handler從消息隊列里取出message
- public synchronized final void cancel() {
- mCancelled = true;
- mHandler.removeMessages(MSG);
- }
- /**
- * Pause the countdown.
- */
- //!add, 暫停,調(diào)用cancel()函數(shù), mCurrentMillisLeft為全局變量自動保存
- public synchronized final void pause() {
- cancel();
- }
- /**
- * Resume the countdown.
- */
- //!add, 恢復函數(shù),根據(jù)mCurrentMillisLeft的值重新添加message開始倒計時
- public synchronized final void resume() {
- mCancelled=false;
- if (mCurrentMillisLeft <= 0) {
- onFinish();
- return ;
- }
- mStopTimeInFuture = SystemClock.elapsedRealtime() + mCurrentMillisLeft;
- mHandler.sendMessage(mHandler.obtainMessage(MSG));
- return ;
- }
- /**
- * Start the countdown.
- */
- //開始倒計時,handler發(fā)送消息到隊列
- public synchronized final CustomCountDownTimer start() {
- mCancelled = false;
- 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.
- */
- //虛擬函數(shù)
- public abstract void onTick(long millisUntilFinished);
- /**
- * Callback fired when the time is up.
- */
- //虛擬函數(shù)
- public abstract void onFinish();
- private static final int MSG = 1;
- // handles counting down
- //handler
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- //同步線程
- synchronized (CustomCountDownTimer.this) {
- //判斷倒計時是否已取消
- if (mCancelled) {
- return;
- }
- //計算當前剩余毫秒數(shù)
- final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
- //根據(jù)剩余毫秒數(shù),或者結束倒計時,或者只延時,或者調(diào)用onTick并延時
- if (millisLeft <= 0) {
- onFinish();
- } else if (millisLeft < mCountdownInterval) {
- // no tick, just delay until done
- onTick(0);//!add
- sendMessageDelayed(obtainMessage(MSG), millisLeft);
- } else {
- long lastTickStart = SystemClock.elapsedRealtime();
- mCurrentMillisLeft=millisLeft;//!add
- 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);
- }
- }
- }
- };
- }
總結
年底了,大家都很忙,大家都多多掙錢,找個好工作,有什么問題就發(fā)信息給我。
責任編輯:武曉燕
來源:
Android開發(fā)編程