Android中方便好用的倒計時類


  

一、使用api提供的類進行操作

Android提供了CountDownTimer來讓我們進行倒計時,可以讓我們很方便的進行倒計時的操作。使用方式也很簡單,下面直接貼代碼就好了:

package com.kale.duitanglib.time;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;

/**
 * @author Jack Tony
 * @brief 官方提供的CountDownTimer來實現
 * 在activity退出后還會持續計時,所以結束時需要判斷當前activity是否在前台
 * @date 2015/4/26
 */
public class SimpleCountDownTimerActivity extends KaleBaseActivity {


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startCountDownTime(6);

    }

    private void startCountDownTime(long time) {
        /**
         * 最簡單的倒計時類,實現了官方的CountDownTimer類(沒有特殊要求的話可以使用)
         * 即使退出activity,倒計時還能進行,因為是創建了后台的線程。
         * 有onTick,onFinsh、cancel和start方法
         */
        CountDownTimer timer = new CountDownTimer(time * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                //每隔countDownInterval秒會回調一次onTick()方法
                Log.d(TAG, "onTick  " + millisUntilFinished / 1000);
            }

            @Override
            public void onFinish() {
                Log.d(TAG, "onFinish -- 倒計時結束");
            }
        };
        timer.start();// 開始計時
        //timer.cancel(); // 取消
    }
}

需要注意的點就是如果你是需要從5秒開始倒計時,每隔一秒進行一次onTick回調,那么你在構造類的時候需要傳入5*1000和1000.此外開始倒計時后會開啟一個后台線程,這樣即使是你的activity被關掉,倒計時還是會執行的,所以你需要防范這個問題。解決思路是在activitydestroy的時候cancel掉它。或者是在倒計時結束時要更新UI的時候進行ui元素是否可見(存在)的判斷。

 

二、讓我們自定義一個倒計時類吧

如果我們想進行更多的功能,比如暫停,回復等等就需要自定義一個倒計時類了,就像下面這樣:

package com.kale.lib.time;

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

/**
 * Jack Tony
 * 自定義的倒計時類,沒有用官方提供的CountDownTimer來實現
 * 有暫停等方法,靈活性強。在activity退出后還會持續計時,所以結束時需要判斷當前activity是否在前台
 * @date 2015/4/24
 */

public abstract class AdvancedCountdownTimer {

    private final long mCountdownInterval;

    private long mTotalTime;

    private long mRemainTime;
    /**
     *
     * @param millisInFuture
     *      表示以毫秒為單位 倒計時的總數 
     *
     *      例如 millisInFuture=1000 表示1秒 
     *
     * @param countDownInterval
     *      表示 間隔 多少微秒 調用一次 onTick 方法 
     *
     *      例如: countDownInterval =1000 ; 表示每1000毫秒調用一次onTick() 
     *
     */
    public AdvancedCountdownTimer(long millisInFuture, long countDownInterval) {
        mTotalTime = millisInFuture;
        mCountdownInterval = countDownInterval;
        mRemainTime = millisInFuture;
    }

    public final void seek(int value) {
        synchronized (AdvancedCountdownTimer.this) {
            mRemainTime = ((100 - value) * mTotalTime) / 100;
        }
    }

    public final void cancel() {
        mHandler.removeMessages(MSG_RUN);
        mHandler.removeMessages(MSG_PAUSE);
    }

    public final void resume() {
        mHandler.removeMessages(MSG_PAUSE);
        mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_RUN));
    }

    public final void pause() {
        mHandler.removeMessages(MSG_RUN);
        mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(MSG_PAUSE));
    }

    public synchronized final AdvancedCountdownTimer start() {
        if (mRemainTime <= 0) {
            onFinish();
            return this;
        }
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RUN),
                mCountdownInterval);
        return this;
    }

    public abstract void onTick(long millisUntilFinished, int percent);

    public abstract void onFinish();

    private static final int MSG_RUN = 1;

    private static final int MSG_PAUSE = 2;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            synchronized (AdvancedCountdownTimer.this) {
                if (msg.what == MSG_RUN) {
                    mRemainTime = mRemainTime - mCountdownInterval;
                    if (mRemainTime <= 0) {
                        onFinish();
                    } else if (mRemainTime < mCountdownInterval) {
                        sendMessageDelayed(obtainMessage(MSG_RUN), mRemainTime);
                    } else {
                        onTick(mRemainTime, new Long(100
                                * (mTotalTime - mRemainTime) / mTotalTime)
                                .intValue());

                        sendMessageDelayed(obtainMessage(MSG_RUN),
                                mCountdownInterval);
                    }
                } else if (msg.what == MSG_PAUSE) {
                }
            }
        }
    };
    
}  

用法和上面完全一樣,直接看代碼:

package com.kale.duitanglib.time;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.Bundle;
import android.util.Log;

/**
 * @author Jack Tony
 * @brief
 * @date 2015/4/26
 */
public class AdvancedCountdownTimerActivity extends KaleBaseActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 8秒倒計時
        com.kale.lib.time.AdvancedCountdownTimer countdownTimer = new com.kale.lib.time.AdvancedCountdownTimer(8 * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished, int percent) {
                //每隔countDownInterval秒會回調一次onTick()方法
                Log.d(TAG,"onTick   " + millisUntilFinished / 1000);
            }

            @Override
            public void onFinish() {
                // 倒計時結束
                Log.d(TAG, "onFinish -- 倒計時結束");
            }
        };
        countdownTimer.start();
    }
}

用這個類的時候同樣需要注意,界面是否被關閉的問題。如果你的界面關閉了,而倒計時仍舊在進行的話,這時再更新UI可能會出現問題。下面貼出一個activity的測試代碼:

package com.kale.countdowntimer;

import com.kale.lib.activity.KaleBaseActivity;

import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

/**
 * @author Jack Tony
 * @date 2015/5/7
 */
public class MainActivity extends KaleBaseActivity {


    private Button normalCountDownTimeButton;

    private Button customCountDownTimeButton;
    
    private TextView timeTextView;

    @Override
    protected int getContentViewId() {
        return R.layout.activity_main;
    }
    
    @Override
    protected void findViews() {
        normalCountDownTimeButton = getView(R.id.normalCountDownTime_button);
        customCountDownTimeButton = getView(R.id.custom_CountDownTime_button);
        timeTextView = getView(R.id.time_textView);
    }

    
    @Override
    protected void setViews() {
        normalCountDownTimeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startNormalCountDownTime(5);
                
            }
        });
        customCountDownTimeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startCustomCountDownTime(5);
            }
        });
    }


    private void startNormalCountDownTime(long time) {
        /**
         * 最簡單的倒計時類,實現了官方的CountDownTimer類(沒有特殊要求的話可以使用)
         * 即使退出activity,倒計時還能進行,因為是創建了后台的線程。
         * 有onTick,onFinsh、cancel和start方法
         */
        CountDownTimer timer = new CountDownTimer(time * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                Log.d(TAG, "onTick  " + millisUntilFinished / 1000);
                timeTextView.setText("還剩" + millisUntilFinished / 1000 + "秒");
            }

            @Override
            public void onFinish() {
                Log.d(TAG, "onFinish -- 倒計時結束");
                timeTextView.setText("結束");
            }
        };
        timer.start();
        //timer.cancel();
    }

    private void startCustomCountDownTime(long time) {
        com.kale.lib.time.AdvancedCountdownTimer countdownTimer = new com.kale.lib.time.AdvancedCountdownTimer(time * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished, int percent) {
                Log.d(TAG, "onTick   " + millisUntilFinished / 1000);
                timeTextView.setText("還剩" + millisUntilFinished / 1000 + "秒");
            }

            @Override
            public void onFinish() {
                Log.d(TAG, "onFinish -- 倒計時結束");
                timeTextView.setText("結束");
            }
        };
        countdownTimer.start();
    }
    
}

 

源碼下載:http://download.csdn.net/detail/shark0017/8671631


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM