// CountDownUtil
import android.os.CountDownTimer;
public class CountDownUtil {
/**
* 倒计时结束的回调接口
*/
public interface FinishDelegate {
void onFinish();
}
/**
* 定期回调的接口
*/
public interface TickDelegate {
void onTick(long pMillisUntilFinished);
}
private final static long ONE_SECOND = 1000;
/**
* 总倒计时时间
*/
private long mMillisInFuture = 0;
/**
* 定期回调的时间 必须大于0 否则会出现ANR
*/
private long mCountDownInterval;
/**
* 倒计时结束的回调
*/
private FinishDelegate mFinishDelegate;
/**
* 定期回调
*/
private TickDelegate mTickDelegate;
private MyCountDownTimer mCountDownTimer;
/**
* 获取 CountDownTimerUtils
*@return CountDownTimerUtils
*/
public static CountDownUtil getCountDownTimer() {
return new CountDownUtil();
}
/**
* 设置定期回调的时间 调用{@link #setTickDelegate(TickDelegate)}
*@param pCountDownInterval 定期回调的时间 必须大于0
*@return CountDownTimerUtils
*/
public CountDownUtil setCountDownInterval(long pCountDownInterval) {
this.mCountDownInterval=pCountDownInterval;
return this;
}
/**
* 设置倒计时结束的回调
*@param pFinishDelegate 倒计时结束的回调接口
*@return CountDownTimerUtils
*/
public CountDownUtil setFinishDelegate(FinishDelegate pFinishDelegate) {
this.mFinishDelegate=pFinishDelegate;
return this;
}
/**
* 设置总倒计时时间
*@param pMillisInFuture 总倒计时时间
*@return CountDownTimerUtils
*/
public CountDownUtil setMillisInFuture(long pMillisInFuture) {
this.mMillisInFuture=pMillisInFuture;
return this;
}
/**
* 设置定期回调
*@param pTickDelegate 定期回调接口
*@return CountDownTimerUtils
*/
public CountDownUtil setTickDelegate(TickDelegate pTickDelegate) {
this.mTickDelegate=pTickDelegate;
return this;
}
public void create() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
mCountDownTimer = null;
}
if (mCountDownInterval <= 0) {
mCountDownInterval = mMillisInFuture + ONE_SECOND;
}
mCountDownTimer = new MyCountDownTimer(mMillisInFuture, mCountDownInterval);
mCountDownTimer.setTickDelegate(mTickDelegate);
mCountDownTimer.setFinishDelegate(mFinishDelegate);
}
/**
* 开始倒计时
*/
public void start() {
if (mCountDownTimer == null) {
create();
}
mCountDownTimer.start();
}
/**
* 取消倒计时
*/
public void cancel() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
private static class MyCountDownTimer extends CountDownTimer {
private FinishDelegate mFinishDelegate;
private TickDelegate mTickDelegate;
public MyCountDownTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
if (mTickDelegate != null) {
mTickDelegate.onTick(millisUntilFinished);
}
}
@Override
public void onFinish() {
if (mFinishDelegate != null) {
mFinishDelegate.onFinish();
}
}
void setFinishDelegate(FinishDelegate pFinishDelegate) {
this.mFinishDelegate=pFinishDelegate;
}
void setTickDelegate(TickDelegate pTickDelegate) {
this.mTickDelegate=pTickDelegate;
}
}
}
----------------------------------------------------------------------------------------
// MainActivity
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
private long countDownInterval = 0;
private SimpleDateFormat mFormatter;
private CountDownUtil mCountDownUtil;
private boolean pauseOn = true;
private Button mPause;
private String mStartHms;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
public void initView(){
mTextView = (TextView) findViewById(R.id.textview);
// 格式化时间 将毫秒格式化为时分秒
mFormatter = new SimpleDateFormat("HH:mm:ss");
// 格式化时间 从0时开始而不是从8时开始
mFormatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));
mPause = (Button) findViewById(R.id.pause);
}
public void initData(){
// 初始化倒计时界面
initCountDown();
}
/**
* 开始倒计时,传入总时间和每一秒要倒计时的时间
*/
private void countDown(final long millisInFuture , long countDownInterval) {
mCountDownUtil = CountDownUtil.getCountDownTimer()
// 倒计时总时间
.setMillisInFuture(millisInFuture)
// 每隔多久回调一次onTick
.setCountDownInterval(countDownInterval)
// 每回调一次onTick执行
.setTickDelegate(new CountDownUtil.TickDelegate() {
@Override
public void onTick(long pMillisUntilFinished) {
String mHms = mFormatter.format(pMillisUntilFinished);
mTextView.setText(mHms);
}
})
// 结束倒计时执行
.setFinishDelegate(new CountDownUtil.FinishDelegate() {
@Override
public void onFinish() {
Toast.makeText(MainActivity.this, millisInFuture + "倒计时完成!", Toast.LENGTH_SHORT).show();
}
});
}
/**
* 初始化倒计时界面
*/
public void initCountDown(){
// 倒计时总时间为3h
long millisInFuture = 1000 * 60 * 60 * 3;
// 每隔1s回调一次onTick
countDownInterval = 1000;
// 格式化倒计时开始时间
mStartHms = mFormatter.format(millisInFuture);
// 将时间显示到界面
mTextView.setText(mStartHms);
// 开始倒计时,传入总时间和每一秒要倒计时的时间
countDown(millisInFuture , countDownInterval);
}
/**
* 点击开始按钮
*/
public void start(View view){
// 点击开始按钮 如果不是倒计时开始和结束时不响应此按钮
if(mTextView.getText().equals("00:00:00") || mTextView.getText().equals(mStartHms)){
// 初始化倒计时界面
initCountDown();
// 开始倒计时
mCountDownUtil.start();
Toast.makeText(this, "开始倒计时!", Toast.LENGTH_SHORT).show();
}
}
/**
* 点击暂停按钮
*/
public void pause(View view) throws ParseException {
// 结束倒计时 不清零
mCountDownUtil.cancel();
// 暂停倒计时
if(pauseOn){
mPause.setText("▲");
pauseOn = false;
Toast.makeText(this, "暂停倒计时!", Toast.LENGTH_SHORT).show();
// 取消暂停
}else{
mPause.setText("||");
pauseOn = true;
// 获取目前的倒计时时间
String now = (String) mTextView.getText();
long time = mFormatter.parse(now).getTime();
// 如果倒计时时间大于0
if(time > 0){
// 继续倒计时
countDown(time , countDownInterval);
mCountDownUtil.start();
Toast.makeText(this, "取消暂停倒计时!", Toast.LENGTH_SHORT).show();
// 如果倒计时时间小于或等于0
}else{
// 倒计时时间异常
Toast.makeText(this, "倒计时时间异常!", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 点击停止按钮
*/
public void stop(View view){
// 结束倒计时并归零
mTextView.setText("00:00:00");
mCountDownUtil.cancel();
Toast.makeText(this, "结束倒计时!", Toast.LENGTH_SHORT).show();
}
}