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

posted @ 2015-04-27 09:50  developer_Kale  阅读(13563)  评论(0编辑  收藏  举报
网站流量统计工具