zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    php+apache+mysql环境搭建
    怎么理解依赖注入
    maven修改远程和本地仓库地址
    idea创建的java web项目打包发布到tomcat
    MYSQL 导入导出数据库文件
    MySQL约束
    mysql字符集校对
    prime
    POJ-2564 01背包问题
    POJ-1564 dfs
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4459216.html
Copyright © 2011-2022 走看看