最近需要一个倒数计时器,要求实现倒数计时,暂停,继续,和快进快退的功能。Android本身提供了一个CountdownTimer的类,采用Handler的方式实现,但是只提供了倒数计时的功能,对于暂停,继续,快进快退功能未提供支持,于是在CounterDownTimer的基础上重写了一个类,最终满足要求。
- 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) {
- }
- }
- }
- };
- }
android自带的CountdownTimer源码:
- /**
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package android.os;
- import android.util.Log;
- /***
- * Schedule a countdown until a time in the future, with
- * regular notifications on intervals along the way.
- *
- * Example of showing a 30 second countdown in a text field:
- *
- * <pre class="prettyprint">
- * new CountdownTimer(30000, 1000) {
- *
- * public void onTick(long millisUntilFinished) {
- * mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
- * }
- *
- * public void onFinish() {
- * mTextField.setText("done!");
- * }
- * }.start();
- * </pre>
- *
- * The calls to {@link #onTick(long)} are synchronized to this object so that
- * one call to {@link #onTick(long)} won't ever occur before the previous
- * callback is complete. This is only relevant when the implementation of
- * {@link #onTick(long)} takes an amount of time to execute that is significant
- * compared to the countdown interval.
- */
- public abstract class CountDownTimer {
- /***
- * Millis since epoch when alarm should stop.
- */
- private final long mMillisInFuture;
- /***
- * The interval in millis that the user receives callbacks
- */
- private final long mCountdownInterval;
- private long mStopTimeInFuture;
- /***
- * @param millisInFuture The number of millis in the future from the call
- * to {@link #start()} until the countdown is done and {@link #onFinish()}
- * is called.
- * @param countDownInterval The interval along the way to receive
- * {@link #onTick(long)} callbacks.
- */
- public CountDownTimer(long millisInFuture, long countDownInterval) {
- mMillisInFuture = millisInFuture;
- mCountdownInterval = countDownInterval;
- }
- /***
- * Cancel the countdown.
- */
- public final void cancel() {
- mHandler.removeMessages(MSG);
- }
- /***
- * Start the countdown.
- */
- public synchronized final CountDownTimer start() {
- if (mMillisInFuture <= 0) {
- onFinish();
- return this;
- }
- mStopTimeInFuture = SystemClock.elapsedRealtime() + mMillisInFuture;
- mHandler.sendMessage(mHandler.obtainMessage(MSG));
- return this;
- }
- /***
- * Callback fired on regular interval.
- * @param millisUntilFinished The amount of time until finished.
- */
- public abstract void onTick(long millisUntilFinished);
- /***
- * Callback fired when the time is up.
- */
- public abstract void onFinish();
- private static final int MSG = 1;
- // handles counting down
- private Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- synchronized (CountDownTimer.this) {
- final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
- if (millisLeft <= 0) {
- onFinish();
- } else if (millisLeft < mCountdownInterval) {
- // no tick, just delay until done
- sendMessageDelayed(obtainMessage(MSG), millisLeft);
- } else {
- long lastTickStart = SystemClock.elapsedRealtime();
- onTick(millisLeft);
- // take into account user's onTick taking time to execute
- long delay = lastTickStart + mCountdownInterval - SystemClock.elapsedRealtime();
- // special case: user's onTick took more than interval to
- // complete, skip to next interval
- while (delay < 0) delay += mCountdownInterval;
- sendMessageDelayed(obtainMessage(MSG), delay);
- }
- }
- }
- };
- }
本文介绍如何在Android中实现一个具备倒计时、暂停、继续和快进快退功能的自定义倒计时器类,通过继承并扩展Android自带的CountdownTimer类来满足特定需求。

4144

被折叠的 条评论
为什么被折叠?



