Separate logic from view
This commit is contained in:
@@ -40,8 +40,6 @@ public class MainActivity extends WearableActivity
|
||||
|
||||
setAmbientEnabled();
|
||||
|
||||
stimer = new SimpleTimer();
|
||||
|
||||
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
Intent ambientModeIntent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
ambientModeIntent.setAction("REFRESH");
|
||||
@@ -52,6 +50,9 @@ public class MainActivity extends WearableActivity
|
||||
SharedPreferences preferences = getSharedPreferences(PREFS_NAME, 0);
|
||||
final long initialTime = preferences.getLong("initialTime", DEFAULT_INITIAL_TIME);
|
||||
|
||||
stimer = new SimpleTimer();
|
||||
stimer.setTotalTime(initialTime);
|
||||
|
||||
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
|
||||
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener()
|
||||
{
|
||||
@@ -59,8 +60,8 @@ public class MainActivity extends WearableActivity
|
||||
public void onLayoutInflated(WatchViewStub stub)
|
||||
{
|
||||
timerView = (TimerView) findViewById(R.id.timerview);
|
||||
timerView.setTime(initialTime);
|
||||
timerView.setTimer(stimer);
|
||||
stimer.setListener(timerView);
|
||||
setAmbientModeListener(timerView);
|
||||
startFixedRateTimer();
|
||||
refreshViews();
|
||||
@@ -99,7 +100,6 @@ public class MainActivity extends WearableActivity
|
||||
{
|
||||
if (timerView != null)
|
||||
{
|
||||
timerView.tick();
|
||||
timerView.invalidate();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class MainActivity extends WearableActivity
|
||||
|
||||
private void scheduleNextRefresh()
|
||||
{
|
||||
long delay = timerView.getMillisecondsUntilNextMinute();
|
||||
long delay = stimer.getMillisecondsUntilNextMinute();
|
||||
if (delay < 0) return;
|
||||
|
||||
Log.d(TAG, "sleeping for " + delay + " milliseconds (" + delay / 1000 / 60.0 +
|
||||
@@ -190,7 +190,7 @@ public class MainActivity extends WearableActivity
|
||||
|
||||
private void savePreferences()
|
||||
{
|
||||
long totalTime = timerView.getTime();
|
||||
long totalTime = stimer.getTotalTime();
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putLong("initialTime", totalTime);
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package org.isoron.simpletimer.model;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class SimpleTimer
|
||||
{
|
||||
private enum TimerState {
|
||||
private static final String TAG = "TimerView";
|
||||
|
||||
private enum TimerState
|
||||
{
|
||||
PAUSED, RUNNING
|
||||
}
|
||||
|
||||
@@ -11,25 +16,35 @@ public class SimpleTimer
|
||||
private long remainingTime;
|
||||
private TimerState state;
|
||||
|
||||
public static final int DEFAULT_INITIAL_TIME = 5 * 60 * 1000;
|
||||
private SimpleTimerListener listener;
|
||||
|
||||
private static final int DEFAULT_INITIAL_TIME = 5 * 60 * 1000;
|
||||
|
||||
public SimpleTimer()
|
||||
{
|
||||
startTime = -1;
|
||||
remainingTime = totalTime = DEFAULT_INITIAL_TIME;
|
||||
state = TimerState.PAUSED;
|
||||
}
|
||||
|
||||
public void setListener(SimpleTimerListener listener)
|
||||
{
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void resume()
|
||||
{
|
||||
if(isRunning()) return;
|
||||
if (isRunning()) return;
|
||||
|
||||
startTime = System.currentTimeMillis();
|
||||
startTime -= totalTime - remainingTime;
|
||||
state = TimerState.RUNNING;
|
||||
}
|
||||
|
||||
public void pause()
|
||||
{
|
||||
if(isPaused()) return;
|
||||
if (isPaused()) return;
|
||||
|
||||
remainingTime = getRemainingTime();
|
||||
state = TimerState.PAUSED;
|
||||
}
|
||||
|
||||
@@ -43,6 +58,12 @@ public class SimpleTimer
|
||||
return state == TimerState.PAUSED;
|
||||
}
|
||||
|
||||
public void flip()
|
||||
{
|
||||
if (isRunning()) pause();
|
||||
else resume();
|
||||
}
|
||||
|
||||
public void reset()
|
||||
{
|
||||
state = TimerState.PAUSED;
|
||||
@@ -50,10 +71,57 @@ public class SimpleTimer
|
||||
}
|
||||
|
||||
public long getRemainingTime()
|
||||
{
|
||||
if (isPaused())
|
||||
{
|
||||
return remainingTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
long elapsedTime = currentTime - startTime;
|
||||
long answer = totalTime - elapsedTime;
|
||||
|
||||
return totalTime - elapsedTime;
|
||||
if (answer >= 0)
|
||||
{
|
||||
return answer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (listener != null) listener.onTimeout();
|
||||
reset();
|
||||
|
||||
return remainingTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getTotalTime()
|
||||
{
|
||||
return totalTime;
|
||||
}
|
||||
|
||||
public void setTotalTime(long totalTime)
|
||||
{
|
||||
this.totalTime = totalTime;
|
||||
this.remainingTime = totalTime;
|
||||
}
|
||||
|
||||
public long getMillisecondsUntilNextMinute()
|
||||
{
|
||||
if (!isRunning()) return -1;
|
||||
return getRemainingTime() % 60000;
|
||||
}
|
||||
|
||||
public void increment(int direction)
|
||||
{
|
||||
if (isRunning()) return;
|
||||
|
||||
int granularity = 60000;
|
||||
if (totalTime + direction <= 3 * 60000) granularity = 10000;
|
||||
|
||||
totalTime = Math.max(0, totalTime + direction * granularity);
|
||||
totalTime = (totalTime / granularity) * granularity;
|
||||
remainingTime = totalTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.isoron.simpletimer.model;
|
||||
|
||||
public interface SimpleTimerListener
|
||||
{
|
||||
public void onTimeout();
|
||||
}
|
||||
@@ -18,20 +18,19 @@ import android.view.View;
|
||||
|
||||
import org.isoron.base.AmbientModeListener;
|
||||
import org.isoron.base.ColorHelper;
|
||||
import org.isoron.simpletimer.MainActivity;
|
||||
import org.isoron.simpletimer.model.SimpleTimer;
|
||||
import org.isoron.simpletimer.model.SimpleTimerListener;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
|
||||
public class TimerView extends View implements AmbientModeListener
|
||||
public class TimerView extends View implements AmbientModeListener, SimpleTimerListener
|
||||
{
|
||||
private static final String TAG = "TimerView";
|
||||
|
||||
private int primaryColor;
|
||||
private int secondaryColor;
|
||||
private int tertiaryColor;
|
||||
|
||||
private int backgroundColor;
|
||||
|
||||
private Paint paint;
|
||||
@@ -47,10 +46,6 @@ public class TimerView extends View implements AmbientModeListener
|
||||
private Vibrator vibrator;
|
||||
|
||||
private int step;
|
||||
private boolean isRunning;
|
||||
private long totalTime;
|
||||
private long remainingTime;
|
||||
private long lastTick;
|
||||
|
||||
private boolean hasLongPressed;
|
||||
private boolean hasMoved = false;
|
||||
@@ -69,10 +64,7 @@ public class TimerView extends View implements AmbientModeListener
|
||||
this.activity = (WearableActivity) ctx;
|
||||
|
||||
step = 0;
|
||||
totalTime = MainActivity.DEFAULT_INITIAL_TIME;
|
||||
remainingTime = totalTime;
|
||||
|
||||
isRunning = false;
|
||||
hasMoved = false;
|
||||
hasLongPressed = false;
|
||||
stimer = null;
|
||||
@@ -121,55 +113,17 @@ public class TimerView extends View implements AmbientModeListener
|
||||
paintAmbient.setTextAlign(Paint.Align.CENTER);
|
||||
}
|
||||
|
||||
public void tick()
|
||||
public void onTimeout()
|
||||
{
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
step = (step + 1) % 2;
|
||||
|
||||
if (remainingTime <= 0)
|
||||
{
|
||||
isRunning = false;
|
||||
}
|
||||
|
||||
if (isRunning)
|
||||
{
|
||||
remainingTime -= (currentTime - lastTick);
|
||||
|
||||
if (remainingTime <= 0)
|
||||
{
|
||||
step = 1;
|
||||
isRunning = false;
|
||||
remainingTime = totalTime;
|
||||
step = 0;
|
||||
vibrator.vibrate(VIBRATION_FINISH, -1);
|
||||
|
||||
PowerManager powerManager =
|
||||
(PowerManager) activity.getSystemService(Activity.POWER_SERVICE);
|
||||
PowerManager.WakeLock wakeLock = powerManager.newWakeLock(
|
||||
(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK |
|
||||
PowerManager.ACQUIRE_CAUSES_WAKEUP), "MyWakelockTag");
|
||||
wakeLock.acquire(500);
|
||||
}
|
||||
}
|
||||
|
||||
lastTick = currentTime;
|
||||
}
|
||||
|
||||
public long getMillisecondsUntilNextMinute()
|
||||
{
|
||||
if (!isRunning) return -1;
|
||||
return remainingTime % 60000;
|
||||
}
|
||||
|
||||
public long getTime()
|
||||
{
|
||||
return totalTime;
|
||||
}
|
||||
|
||||
public void setTime(long totalTime)
|
||||
{
|
||||
this.totalTime = totalTime;
|
||||
this.remainingTime = totalTime;
|
||||
PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
|
||||
"MyWakelockTag");
|
||||
wakeLock.acquire(5000);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,6 +149,8 @@ public class TimerView extends View implements AmbientModeListener
|
||||
paint = paintInteractive;
|
||||
if (ambientMode) paint = paintAmbient;
|
||||
|
||||
step = (step + 1) % 2;
|
||||
|
||||
clearBackground(canvas);
|
||||
drawTimer(canvas);
|
||||
drawCurrentTime(canvas);
|
||||
@@ -226,6 +182,8 @@ public class TimerView extends View implements AmbientModeListener
|
||||
else paint.setColor(primaryColor);
|
||||
long minutes;
|
||||
|
||||
long remainingTime = stimer.getRemainingTime();
|
||||
|
||||
if (ambientMode)
|
||||
{
|
||||
minutes = (long) (60 * Math.ceil(remainingTime / 1000 / 60.0));
|
||||
@@ -238,7 +196,7 @@ public class TimerView extends View implements AmbientModeListener
|
||||
minutes = (long) (60 * Math.floor(remainingTime / 1000 / 60.0));
|
||||
long seconds = remainingTime / 1000 % 60;
|
||||
|
||||
if (isRunning || step == 1)
|
||||
if (stimer.isRunning() || step == 1)
|
||||
{
|
||||
paint.setTextSize(size * 0.25f);
|
||||
float minutesWidth = paint.measureText(String.format("%d", minutes / 60));
|
||||
@@ -273,14 +231,16 @@ public class TimerView extends View implements AmbientModeListener
|
||||
|
||||
private void clearBackground(Canvas canvas)
|
||||
{
|
||||
paint.setColor(backgroundColor);
|
||||
if(ambientMode) paint.setColor(Color.BLACK);
|
||||
else paint.setColor(backgroundColor);
|
||||
|
||||
canvas.drawRect(screenRect, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterAmbient(Bundle ambientDetails)
|
||||
{
|
||||
if (!isRunning) activity.finishAffinity();
|
||||
if (!stimer.isRunning()) activity.finishAffinity();
|
||||
|
||||
ambientMode = true;
|
||||
Log.d(TAG, "onEnterAmbient()");
|
||||
@@ -302,7 +262,8 @@ public class TimerView extends View implements AmbientModeListener
|
||||
class TouchListener implements View.OnTouchListener
|
||||
{
|
||||
private float prevY;
|
||||
private long prevTime;
|
||||
private float prevX;
|
||||
private long prevDy;
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
@@ -313,31 +274,35 @@ public class TimerView extends View implements AmbientModeListener
|
||||
{
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
prevY = event.getY();
|
||||
prevTime = remainingTime;
|
||||
prevX = event.getX();
|
||||
hasMoved = false;
|
||||
hasLongPressed = false;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
float dy = (event.getY() - prevY) / box;
|
||||
int dy = (int) ((prevY - event.getY()) / box);
|
||||
int dx = (int) ((prevX - event.getX()) / box);
|
||||
|
||||
if (Math.abs(dy) < 1) break;
|
||||
|
||||
|
||||
hasMoved = true;
|
||||
if (dy == prevDy) break;
|
||||
|
||||
if (isRunning) break;
|
||||
stimer.increment(dy > 0 ? 1 : -1);
|
||||
|
||||
totalTime = Math.max(GRANULARITY, prevTime - (long) dy * GRANULARITY);
|
||||
totalTime = (totalTime / GRANULARITY) * GRANULARITY;
|
||||
remainingTime = totalTime;
|
||||
|
||||
step = 1;
|
||||
step = 0;
|
||||
prevDy = dy;
|
||||
prevY = event.getY();
|
||||
invalidate();
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (hasMoved) break;
|
||||
if (hasLongPressed) break;
|
||||
prevDy = -100;
|
||||
|
||||
isRunning = !isRunning;
|
||||
stimer.flip();
|
||||
|
||||
vibrator.vibrate(80);
|
||||
invalidate();
|
||||
@@ -355,8 +320,7 @@ public class TimerView extends View implements AmbientModeListener
|
||||
{
|
||||
if (hasMoved) return false;
|
||||
|
||||
remainingTime = totalTime;
|
||||
isRunning = false;
|
||||
stimer.reset();
|
||||
|
||||
vibrator.vibrate(250);
|
||||
hasLongPressed = true;
|
||||
|
||||
Reference in New Issue
Block a user