博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Android 升级版倒数计时器

Posted on 2010-08-21 10:45  qzxia  阅读(1359)  评论(0)    收藏  举报

最近需要一个倒数计时器,要求实现倒数计时,暂停,继续,和快进快退的功能。Android本身提供了一个CountdownTimer的类,采用Handler的方式实现,但是只提供了倒数计时的功能,对于暂停,继续,快进快退功能未提供支持,于是在CounterDownTimer的基础上重写了一个类,最终满足要求。

package com.jason.stopwatch.util;

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

public abstract class AdvancedCountdownTimer {

	private final long mCountdownInterval;

	private long mTotalTime;

	private long mRemainTime;

	
	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) {

				}
			}
		}
	};
}