diff --git a/app/src/main/java/com/philliphsu/clock2/timers/CountdownChronometer.java b/app/src/main/java/com/philliphsu/clock2/timers/CountdownChronometer.java index 6b00b91..1febb28 100644 --- a/app/src/main/java/com/philliphsu/clock2/timers/CountdownChronometer.java +++ b/app/src/main/java/com/philliphsu/clock2/timers/CountdownChronometer.java @@ -38,8 +38,8 @@ public class CountdownChronometer extends TextView { private long mBase; private long mNow; // the currently displayed time -// private long mPause; // the time at which pause() was called -// private long mDuration; + private long mPause; // the time at which pause() was called + private long mDuration; private boolean mVisible; private boolean mStarted; private boolean mRunning; @@ -110,7 +110,7 @@ public class CountdownChronometer extends TextView { // @android.view.RemotableViewMethod public void setBase(long base) { mBase = base; -// mDuration = base - SystemClock.elapsedRealtime(); + mDuration = base - SystemClock.elapsedRealtime(); dispatchChronometerTick(); updateText(SystemClock.elapsedRealtime()); } @@ -126,16 +126,28 @@ public class CountdownChronometer extends TextView { * Equivalent to {@link #setBase(long) setBase(SystemClock.elapsedRealtime() + duration)}. */ public void setDuration(long duration) { -// mDuration = duration; setBase(SystemClock.elapsedRealtime() + duration); } -// /** -// * Return the duration of this countdown. -// */ -// public long getDuration() { -// return mDuration; -// } + /** + * Return the duration of this countdown. + */ + public long getDuration() { + return mDuration; + } + + /** + * If the base time has not passed yet, adds one minute to it. + * Otherwise, sets another countdown for one minute from now. + */ + public void addOneMinute() { + if (getBase() <= SystemClock.elapsedRealtime()) { + // Expired already + setDuration(60 * 1000); + } else { + setBase(getBase() + 60 * 1000); + } + } /** * Sets the format string used for display. The Chronometer will display @@ -189,10 +201,18 @@ public class CountdownChronometer extends TextView { * make sure that each start() call has a reciprocal call to {@link #stop}. */ public void start() { - // If we don't do this, the text display won't get to count - // all of the seconds in the set duration. Time passes - // between the call to setDuration(), or setBase(), and start(). -// mBase = SystemClock.elapsedRealtime() + mDuration; + if (mPause == 0) { + // Do a cold start. + // Every time BEFORE we do a cold start, we have to set the base again + // because time passes between the instant we first call setBase() and the + // instant we start the timer. Otherwise, after we start, that interval of time + // would immediately get cut off from the duration. + setDuration(mDuration); + } else if (mPause > 0) { + // Resume from a pause + setBase(getBase() + SystemClock.elapsedRealtime() - mPause); + mPause = 0; + } mStarted = true; updateRunning(); } @@ -207,25 +227,33 @@ public class CountdownChronometer extends TextView { public void stop() { mStarted = false; updateRunning(); -// setDuration(mDuration); // Reset the text display } -// public void pause() { -// if (mPause == 0 && mRunning) { -// mPause = SystemClock.elapsedRealtime(); -// } -// mStarted = false; -// updateRunning(); -// } -// -// public void resume() { -// if (mPause > 0 && !mRunning) { -// mBase += SystemClock.elapsedRealtime() - mPause; -// mPause = 0; -// } -// mStarted = true; -// updateRunning(); -// } + /** + * Like {@link #stop()}, but resets the base and the view display. + */ + public void reset() { + stop(); + setDuration(mDuration); + mPause = 0; + } + + /** + * Like {@link #stop()}, but begins measuring the timeout between now + * and the next call to {@link #start()}, so that the base can be increased + * by this amount. In effect, the countdown can be resumed without being + * affected by the timeout. + */ + public void pause() { + if (mPause == 0 && mRunning) { + stop(); + mPause = SystemClock.elapsedRealtime(); + } + } + + public boolean isRunning() { + return mRunning; + } /** * The same as calling {@link #start} or {@link #stop}. diff --git a/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java b/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java index 980ce66..14df4b8 100644 --- a/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java +++ b/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java @@ -38,28 +38,10 @@ public class TimerViewHolder extends BaseViewHolder { @OnClick(R.id.start_pause) void startPause() { - // Every time BEFORE you call start() on the chronometer, you have to - // call setBase() again because time passes between the time we first call - // setBase() and the time we start the timer. Otherwise, after start() is called, - // that period of time would appear to have counted off already, as the text - // display jumps downward by that amount of time from its initial duration. - Timer t = getItem(); - if (t.hasStarted()) { - if (t.isRunning()) { - // Records the start of this pause - t.pause(); - // Stops the counting, but does not reset any values - mChronometer.stop(); - } else { - // Pushes up the end time - t.resume(); - // Use the new end time as reference from now - mChronometer.setBase(t.endTime()); - mChronometer.start(); - } + if (mChronometer.isRunning()) { + mChronometer.pause(); } else { - t.start(); - mChronometer.setBase(t.endTime()); + // Cold starts, or resumes. mChronometer.start(); } }