From d845f241e96c77687951ec99fd7b1f3715a836ad Mon Sep 17 00:00:00 2001 From: Phillip Hsu Date: Sat, 6 Aug 2016 00:06:15 -0700 Subject: [PATCH] New ringtone activity layout --- .../clock2/AsyncTimersTableUpdateHandler.java | 4 + .../clock2/alarms/AlarmActivity.java | 63 +++++++++----- .../clock2/ringtone/RingtoneActivity.java | 63 ++++++++++++-- .../clock2/timers/TimesUpActivity.java | 59 +++++++++++-- app/src/main/res/layout/activity_ringtone.xml | 87 +++++++++++++------ .../layout/content_header_alarm_activity.xml | 6 ++ .../content_header_timesup_activity.xml | 7 ++ app/src/main/res/values/dimens.xml | 20 ++++- app/src/main/res/values/strings.xml | 3 + 9 files changed, 246 insertions(+), 66 deletions(-) create mode 100644 app/src/main/res/layout/content_header_alarm_activity.xml create mode 100644 app/src/main/res/layout/content_header_timesup_activity.xml diff --git a/app/src/main/java/com/philliphsu/clock2/AsyncTimersTableUpdateHandler.java b/app/src/main/java/com/philliphsu/clock2/AsyncTimersTableUpdateHandler.java index bf4f704..0852a3c 100644 --- a/app/src/main/java/com/philliphsu/clock2/AsyncTimersTableUpdateHandler.java +++ b/app/src/main/java/com/philliphsu/clock2/AsyncTimersTableUpdateHandler.java @@ -8,6 +8,7 @@ import android.content.Intent; import com.philliphsu.clock2.alarms.ScrollHandler; import com.philliphsu.clock2.model.TimersTableManager; import com.philliphsu.clock2.timers.TimerNotificationService; +import com.philliphsu.clock2.timers.TimerRingtoneService; import com.philliphsu.clock2.timers.TimesUpActivity; /** @@ -77,5 +78,8 @@ public final class AsyncTimersTableUpdateHandler extends AsyncDatabaseTableUpdat if (removeNotification) { TimerNotificationService.cancelNotification(getContext(), timer.getId()); } + // Won't do anything if not actually started + getContext().stopService(new Intent(getContext(), TimerRingtoneService.class)); + // TODO: Do we need to finish TimesUpActivity? } } diff --git a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmActivity.java b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmActivity.java index 32cb18e..bd29737 100644 --- a/app/src/main/java/com/philliphsu/clock2/alarms/AlarmActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/alarms/AlarmActivity.java @@ -1,8 +1,7 @@ package com.philliphsu.clock2.alarms; import android.os.Bundle; -import android.view.View; -import android.widget.Button; +import android.view.ViewGroup; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.R; @@ -21,26 +20,6 @@ public class AlarmActivity extends RingtoneActivity { // TODO: If the upcoming alarm notification isn't present, verify other notifications aren't affected. // This could be the case if we're starting a new instance of this activity after leaving the first launch. mAlarmController.removeUpcomingAlarmNotification(getRingingObject()); - // TODO: Butterknife binding - Button snooze = (Button) findViewById(R.id.btn_snooze); - snooze.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - snooze(); - } - }); - Button dismiss = (Button) findViewById(R.id.btn_dismiss); - dismiss.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - dismiss(); - } - }); - } - - @Override - public int layoutResource() { - return R.layout.activity_ringtone; } @Override @@ -48,14 +27,50 @@ public class AlarmActivity extends RingtoneActivity { return AlarmRingtoneService.class; } - private void snooze() { + @Override + protected CharSequence getHeaderTitle() { + return getRingingObject().label(); + } + + @Override + protected void getHeaderContent(ViewGroup parent) { + // TODO: Consider applying size span on the am/pm label + getLayoutInflater().inflate(R.layout.content_header_alarm_activity, parent, true); + } + + @Override + protected int getAutoSilencedDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected int getAutoSilencedText() { + return R.string.alarm_auto_silenced_text; + } + + @Override + protected int getLeftButtonDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected int getRightButtonDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected void onLeftButtonClick() { mAlarmController.snoozeAlarm(getRingingObject()); // Can't call dismiss() because we don't want to also call cancelAlarm()! Why? For example, // we don't want the alarm, if it has no recurrence, to be turned off right now. stopAndFinish(); } - private void dismiss() { + @Override + protected void onRightButtonClick() { // TODO do we really need to cancel the intent and alarm? mAlarmController.cancelAlarm(getRingingObject(), false); stopAndFinish(); diff --git a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java index c09905f..7026504 100644 --- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java @@ -5,13 +5,24 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Parcelable; -import android.support.annotation.LayoutRes; +import android.support.annotation.DrawableRes; +import android.support.annotation.StringRes; +import android.support.design.widget.FloatingActionButton; import android.support.v7.app.AppCompatActivity; import android.view.View; +import android.view.ViewGroup; import android.view.WindowManager; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import com.philliphsu.clock2.R; import com.philliphsu.clock2.util.LocalBroadcastHelper; +import butterknife.Bind; +import butterknife.ButterKnife; +import butterknife.OnClick; + /** * An example full-screen activity that shows and hides the system UI (i.e. * status bar and navigation/system bar) with user interaction. @@ -26,16 +37,48 @@ public abstract class RingtoneActivity extends AppCompatAc private static boolean sIsAlive = false; private T mRingingObject; - // TODO: Should we extend from BaseActivity instead? - @LayoutRes - public abstract int layoutResource(); + @Bind(R.id.title) TextView mHeaderTitle; + @Bind(R.id.auto_silenced_text) TextView mAutoSilencedText; + @Bind(R.id.ok) Button mOkButton; + @Bind(R.id.btn_left) FloatingActionButton mLeftButton; + @Bind(R.id.btn_right) FloatingActionButton mRightButton; protected abstract Class getRingtoneServiceClass(); + protected abstract CharSequence getHeaderTitle(); + + /** + * Subclasses are responsible for adding their content view + * to the provided parent container. + */ + protected abstract void getHeaderContent(ViewGroup parent); + + @DrawableRes + protected abstract int getAutoSilencedDrawable(); + + @StringRes + protected abstract int getAutoSilencedText(); + + @DrawableRes + protected abstract int getLeftButtonDrawable(); + + @DrawableRes + protected abstract int getRightButtonDrawable(); + + @OnClick(R.id.btn_left) + protected abstract void onLeftButtonClick(); + + @OnClick(R.id.btn_right) + protected abstract void onRightButtonClick(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(layoutResource()); + setContentView(R.layout.activity_ringtone); + ButterKnife.bind(this); + + if ((mRingingObject = getIntent().getParcelableExtra(EXTRA_RINGING_OBJECT)) == null) + throw new IllegalStateException("Cannot start RingtoneActivity without a ringing object"); sIsAlive = true; getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); @@ -43,9 +86,13 @@ public abstract class RingtoneActivity extends AppCompatAc getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); - if ((mRingingObject = getIntent().getParcelableExtra(EXTRA_RINGING_OBJECT)) == null) { - throw new IllegalStateException("Cannot start RingtoneActivity without a ringing object"); - } + mHeaderTitle.setText(getHeaderTitle()); // TOneverDO: call before assigning mRingingObject + getHeaderContent((LinearLayout) findViewById(R.id.header)); + mAutoSilencedText.setCompoundDrawablesWithIntrinsicBounds(0, getAutoSilencedDrawable(), 0, 0); + mAutoSilencedText.setText(getAutoSilencedText()); + mLeftButton.setImageResource(getLeftButtonDrawable()); + mRightButton.setImageResource(getRightButtonDrawable()); + Intent intent = new Intent(this, getRingtoneServiceClass()) .putExtra(EXTRA_RINGING_OBJECT, mRingingObject); startService(intent); diff --git a/app/src/main/java/com/philliphsu/clock2/timers/TimesUpActivity.java b/app/src/main/java/com/philliphsu/clock2/timers/TimesUpActivity.java index ec0182c..393912e 100644 --- a/app/src/main/java/com/philliphsu/clock2/timers/TimesUpActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/timers/TimesUpActivity.java @@ -2,6 +2,8 @@ package com.philliphsu.clock2.timers; import android.content.Intent; import android.os.Bundle; +import android.os.SystemClock; +import android.view.ViewGroup; import com.philliphsu.clock2.R; import com.philliphsu.clock2.Timer; @@ -17,13 +19,60 @@ public class TimesUpActivity extends RingtoneActivity { TimerNotificationService.cancelNotification(this, getRingingObject().getId()); } - @Override - public int layoutResource() { - return R.layout.activity_ringtone; - } - @Override protected Class getRingtoneServiceClass() { return TimerRingtoneService.class; } + + @Override + protected CharSequence getHeaderTitle() { + return getRingingObject().label(); + } + + @Override + protected void getHeaderContent(ViewGroup parent) { + // Inflate the content and apply the parent's layout params, but don't + // attach it to the parent yet. This is so the return value can be + // the root of the inflated content, and not the parent. Alternatively, + // we could set an id on the root of the content's layout and find it + // from the returned parent. + CountdownChronometer countdown = (CountdownChronometer) getLayoutInflater() + .inflate(R.layout.content_header_timesup_activity, parent, false); + countdown.setBase(SystemClock.elapsedRealtime()); + countdown.start(); + parent.addView(countdown); + } + + @Override + protected int getAutoSilencedDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected int getAutoSilencedText() { + return R.string.timer_auto_silenced_text; + } + + @Override + protected int getLeftButtonDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected int getRightButtonDrawable() { + // TODO: correct icon + return R.drawable.ic_half_day_1_black_24dp; + } + + @Override + protected void onLeftButtonClick() { + + } + + @Override + protected void onRightButtonClick() { + + } } diff --git a/app/src/main/res/layout/activity_ringtone.xml b/app/src/main/res/layout/activity_ringtone.xml index 37dbd21..27ad35c 100644 --- a/app/src/main/res/layout/activity_ringtone.xml +++ b/app/src/main/res/layout/activity_ringtone.xml @@ -1,44 +1,75 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:background="@color/colorPrimary"> - - + android:layout_height="wrap_content" + android:layout_marginTop="@dimen/activity_vertical_margin" + android:orientation="vertical" + android:gravity="center_horizontal"> + + + + + android:orientation="vertical" + android:layout_gravity="center" + android:gravity="center" + android:visibility="gone"> + +