一、使用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();
} }