Created TimerController

This commit is contained in:
Phillip Hsu 2016-07-27 13:41:36 -07:00
parent ec49204755
commit ac56357b4b
5 changed files with 70 additions and 68 deletions

View File

@ -11,7 +11,7 @@ import java.util.concurrent.TimeUnit;
*/ */
@AutoValue @AutoValue
public abstract class Timer { public abstract class Timer {
private static final int MINUTE = 60 * 1000; private static final long MINUTE = TimeUnit.MINUTES.toMillis(1);
private long id; private long id;
private long endTime; private long endTime;

View File

@ -38,8 +38,6 @@ public class CountdownChronometer extends TextView {
private long mBase; private long mBase;
private long mNow; // the currently displayed time private long mNow; // the currently displayed time
private long mPause; // the time at which pause() was called
private long mDuration;
private boolean mVisible; private boolean mVisible;
private boolean mStarted; private boolean mStarted;
private boolean mRunning; private boolean mRunning;
@ -110,7 +108,6 @@ public class CountdownChronometer extends TextView {
// @android.view.RemotableViewMethod // @android.view.RemotableViewMethod
public void setBase(long base) { public void setBase(long base) {
mBase = base; mBase = base;
mDuration = base - SystemClock.elapsedRealtime();
dispatchChronometerTick(); dispatchChronometerTick();
updateText(SystemClock.elapsedRealtime()); updateText(SystemClock.elapsedRealtime());
} }
@ -129,26 +126,6 @@ public class CountdownChronometer extends TextView {
setBase(SystemClock.elapsedRealtime() + duration); setBase(SystemClock.elapsedRealtime() + duration);
} }
/**
* 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 * Sets the format string used for display. The Chronometer will display
* this string, with the first "%s" replaced by the current timer value in * this string, with the first "%s" replaced by the current timer value in
@ -201,18 +178,6 @@ public class CountdownChronometer extends TextView {
* make sure that each start() call has a reciprocal call to {@link #stop}. * make sure that each start() call has a reciprocal call to {@link #stop}.
*/ */
public void start() { public void start() {
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; mStarted = true;
updateRunning(); updateRunning();
} }
@ -229,32 +194,6 @@ public class CountdownChronometer extends TextView {
updateRunning(); 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}. * The same as calling {@link #start} or {@link #stop}.
* @hide pending API council approval * @hide pending API council approval

View File

@ -0,0 +1,51 @@
package com.philliphsu.clock2.timers;
import android.os.SystemClock;
import com.philliphsu.clock2.Timer;
/**
* Created by Phillip Hsu on 7/27/2016.
*/
public class TimerController {
private final Timer mTimer;
private final CountdownChronometer mChronometer;
public TimerController(Timer timer, CountdownChronometer chronometer) {
mTimer = timer;
mChronometer = chronometer;
init();
}
private void init() {
mChronometer.setBase(SystemClock.elapsedRealtime() + mTimer.duration());
}
public void start() {
mTimer.start();
mChronometer.setBase(mTimer.endTime());
mChronometer.start();
}
public void pause() {
mTimer.pause();
mChronometer.stop();
}
public void resume() {
mTimer.resume();
mChronometer.setBase(mTimer.endTime());
mChronometer.start();
}
public void stop() {
mTimer.stop();
mChronometer.stop();
init();
}
public void addOneMinute() {
mTimer.addOneMinute();
mChronometer.setBase(mTimer.endTime());
}
}

View File

@ -18,6 +18,8 @@ import butterknife.OnClick;
*/ */
public class TimerViewHolder extends BaseViewHolder<Timer> { public class TimerViewHolder extends BaseViewHolder<Timer> {
private TimerController mController;
@Bind(R.id.label) TextView mLabel; @Bind(R.id.label) TextView mLabel;
@Bind(R.id.duration) CountdownChronometer mChronometer; @Bind(R.id.duration) CountdownChronometer mChronometer;
@Bind(R.id.progress_bar) ProgressBar mProgressBar; @Bind(R.id.progress_bar) ProgressBar mProgressBar;
@ -25,6 +27,7 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
@Bind(R.id.start_pause) ImageButton mStartPause; @Bind(R.id.start_pause) ImageButton mStartPause;
@Bind(R.id.stop) ImageButton mStop; @Bind(R.id.stop) ImageButton mStop;
// TODO: Controller param
public TimerViewHolder(ViewGroup parent, OnListItemInteractionListener<Timer> listener) { public TimerViewHolder(ViewGroup parent, OnListItemInteractionListener<Timer> listener) {
super(parent, R.layout.item_timer, listener); super(parent, R.layout.item_timer, listener);
} }
@ -33,16 +36,23 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
public void onBind(Timer timer) { public void onBind(Timer timer) {
super.onBind(timer); super.onBind(timer);
bindLabel(timer.label()); bindLabel(timer.label());
// We can't create the controller until this VH binds, because
// the chronometer only exists after this point.
mController = new TimerController(timer, mChronometer);
bindChronometer(timer); bindChronometer(timer);
} }
@OnClick(R.id.start_pause) @OnClick(R.id.start_pause)
void startPause() { void startPause() {
if (mChronometer.isRunning()) { Timer t = getItem();
mChronometer.pause(); if (t.isRunning()) {
mController.pause();
} else { } else {
// Cold starts, or resumes. if (t.hasStarted()) {
mChronometer.start(); mController.resume();
} else {
mController.start();
}
} }
} }
@ -64,7 +74,9 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
if (!timer.hasStarted()) { if (!timer.hasStarted()) {
// Set the initial text // Set the initial text
mChronometer.setDuration(timer.duration()); // TODO: Verify the controller should already have initialized
// the text when it was constructed.
// mChronometer.setDuration(timer.duration());
} else if (timer.isRunning()) { } else if (timer.isRunning()) {
// Re-initialize the base // Re-initialize the base
mChronometer.setBase(timer.endTime()); mChronometer.setBase(timer.endTime());

View File

@ -18,7 +18,7 @@ public class DummyContent {
*/ */
public static final List<Timer> ITEMS = new ArrayList<>(); public static final List<Timer> ITEMS = new ArrayList<>();
private static final int COUNT = 1; private static final int COUNT = 10;
static { static {
// Add some sample items. // Add some sample items.