diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6d99fa7..e09d9db 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -36,6 +36,15 @@
android:exported="false">
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/philliphsu/clock2/BaseActivity.java b/app/src/main/java/com/philliphsu/clock2/BaseActivity.java
new file mode 100644
index 0000000..88b439f
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/BaseActivity.java
@@ -0,0 +1,73 @@
+package com.philliphsu.clock2;
+
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.support.annotation.CallSuper;
+import android.support.annotation.LayoutRes;
+import android.support.annotation.MenuRes;
+import android.support.annotation.Nullable;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.Toolbar;
+import android.view.Menu;
+
+import butterknife.Bind;
+import butterknife.ButterKnife;
+
+/**
+ * Created by Phillip Hsu on 5/31/2016.
+ */
+public abstract class BaseActivity extends AppCompatActivity {
+
+ @Nullable @Bind(R.id.toolbar) Toolbar mToolbar;
+ private Menu mMenu;
+
+ @LayoutRes protected abstract int layoutResId();
+ @MenuRes protected abstract int menuResId();
+
+ @CallSuper
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(layoutResId());
+ // Initialize the associated SharedPreferences file with default values
+ // for each preference when the user first opens your application.
+ // When false, the system sets the default values only if this method has
+ // never been called in the past (or the KEY_HAS_SET_DEFAULT_VALUES in the
+ // default value shared preferences file is false).
+//TODO PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+ // Direct volume changes to the alarm stream
+ setVolumeControlStream(AudioManager.STREAM_ALARM);
+ ButterKnife.bind(this);
+ if (mToolbar != null) {
+ setSupportActionBar(mToolbar);
+ ActionBar ab = getSupportActionBar();
+ if (ab != null) {
+ ab.setDisplayHomeAsUpEnabled(isDisplayHomeUpEnabled());
+ ab.setDisplayShowTitleEnabled(isDisplayShowTitleEnabled());
+ }
+ }
+ }
+
+ @Override
+ public final boolean onCreateOptionsMenu(Menu menu) {
+ if (menuResId() != 0) {
+ getMenuInflater().inflate(menuResId(), menu);
+ mMenu = menu;
+ }
+ return super.onCreateOptionsMenu(menu);
+ }
+
+ @Nullable
+ public final Menu getMenu() {
+ return mMenu;
+ }
+
+ protected boolean isDisplayHomeUpEnabled() {
+ return true;
+ }
+
+ protected boolean isDisplayShowTitleEnabled() {
+ return false;
+ }
+}
diff --git a/app/src/main/java/com/philliphsu/clock2/DaysOfWeek.java b/app/src/main/java/com/philliphsu/clock2/DaysOfWeek.java
index ba8f615..2990a7f 100644
--- a/app/src/main/java/com/philliphsu/clock2/DaysOfWeek.java
+++ b/app/src/main/java/com/philliphsu/clock2/DaysOfWeek.java
@@ -43,7 +43,7 @@ public class DaysOfWeek {
sAppContext = context.getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// TODO First day of week preference. Entries are the full days' names and values are their respective integers.
- String preferredFirstDay = prefs.getString("", "0");
+ String preferredFirstDay = prefs.getString("", "6");
if (sInstance == null || !preferredFirstDay.equals(sLastPreferredFirstDay)) {
sLastPreferredFirstDay = preferredFirstDay;
sInstance = new DaysOfWeek(Integer.parseInt(preferredFirstDay));
diff --git a/app/src/main/java/com/philliphsu/clock2/MainActivity.java b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
index 395b4df..c7adeab 100644
--- a/app/src/main/java/com/philliphsu/clock2/MainActivity.java
+++ b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
@@ -6,25 +6,22 @@ import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
-import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
-import android.support.v7.app.AppCompatActivity;
-import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
-import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.philliphsu.clock2.alarms.AlarmsFragment;
+import com.philliphsu.clock2.editalarm.EditAlarmActivity;
import com.philliphsu.clock2.ringtone.RingtoneActivity;
-public class MainActivity extends AppCompatActivity implements AlarmsFragment.OnAlarmInteractionListener {
+public class MainActivity extends BaseActivity implements AlarmsFragment.OnAlarmInteractionListener {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
@@ -44,10 +41,7 @@ public class MainActivity extends AppCompatActivity implements AlarmsFragment.On
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
@@ -63,6 +57,8 @@ public class MainActivity extends AppCompatActivity implements AlarmsFragment.On
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
+ startActivity(new Intent(MainActivity.this, EditAlarmActivity.class));
+ /*
scheduleAlarm();
Snackbar.make(view, "Alarm set for 1 minute from now", Snackbar.LENGTH_INDEFINITE)
.setAction("Dismiss", new View.OnClickListener() {
@@ -77,17 +73,24 @@ public class MainActivity extends AppCompatActivity implements AlarmsFragment.On
sendBroadcast(intent);
}
}).show();
+ */
}
});
-
}
+ @Override
+ protected int layoutResId() {
+ return R.layout.activity_main;
+ }
@Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
+ protected int menuResId() {
+ return R.menu.menu_main;
+ }
+
+ @Override
+ protected boolean isDisplayHomeUpEnabled() {
+ return false;
}
@Override
@@ -180,7 +183,7 @@ public class MainActivity extends AppCompatActivity implements AlarmsFragment.On
@Override
public void onListItemInteraction(Alarm item) {
- // TODO react to click
+ startActivity(new Intent(this, EditAlarmActivity.class));
}
private void scheduleAlarm() {
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java b/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java
new file mode 100644
index 0000000..cc9e7bb
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/EditAlarmActivity.java
@@ -0,0 +1,59 @@
+package com.philliphsu.clock2.editalarm;
+
+import android.os.Bundle;
+import android.support.v7.widget.SwitchCompat;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ToggleButton;
+
+import com.philliphsu.clock2.BaseActivity;
+import com.philliphsu.clock2.DaysOfWeek;
+import com.philliphsu.clock2.R;
+
+import butterknife.Bind;
+
+public class EditAlarmActivity extends BaseActivity {
+
+ @Bind(R.id.save) Button mSave;
+ @Bind(R.id.delete) Button mDelete;
+ @Bind(R.id.on_off) SwitchCompat mSwitch;
+ @Bind(R.id.input_time) EditText mTimeText;
+ @Bind({R.id.day0, R.id.day1, R.id.day2, R.id.day3, R.id.day4, R.id.day5, R.id.day6})
+ ToggleButton[] mDays;
+ @Bind(R.id.label) EditText mLabel;
+ @Bind(R.id.ringtone) Button mRingtone;
+ @Bind(R.id.vibrate) CheckBox mVibrate;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setWeekDaysText();
+ getSupportActionBar().setTitle("Snoozing until 12:40 PM");
+ }
+
+ @Override
+ protected int layoutResId() {
+ return R.layout.activity_edit_alarm;
+ }
+
+ @Override
+ protected int menuResId() {
+ return 0;
+ }
+
+ @Override
+ protected boolean isDisplayShowTitleEnabled() {
+ return true;
+ }
+
+ private void setWeekDaysText() {
+ for (int i = 0; i < mDays.length; i++) {
+ int weekDay = DaysOfWeek.getInstance(this).weekDay(i);
+ String label = DaysOfWeek.getLabel(weekDay);
+ mDays[i].setTextOn(label);
+ mDays[i].setTextOff(label);
+ mDays[i].setChecked(mDays[i].isChecked()); // force update the text, otherwise it won't be shown
+ }
+ }
+}
diff --git a/app/src/main/res/layout/activity_edit_alarm.xml b/app/src/main/res/layout/activity_edit_alarm.xml
new file mode 100644
index 0000000..50469f4
--- /dev/null
+++ b/app/src/main/res/layout/activity_edit_alarm.xml
@@ -0,0 +1,195 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_edit_alarm.xml b/app/src/main/res/layout/content_edit_alarm.xml
new file mode 100644
index 0000000..8642e7e
--- /dev/null
+++ b/app/src/main/res/layout/content_edit_alarm.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 3e5f0f6..f7e82e0 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -9,4 +9,6 @@
16dp4dp48sp
+ 180dp
+ 16dp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c2dd2f0..44e2992 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -7,6 +7,9 @@
Dummy ButtonDUMMY\nCONTENTEditAlarmActivity
+ Save
+ Delete
+ 12:00 AMSunMon
@@ -16,4 +19,93 @@
FriSatEvery day
+
+ "Material is the metaphor.\n\n"
+
+ "A material metaphor is the unifying theory of a rationalized space and a system of motion."
+ "The material is grounded in tactile reality, inspired by the study of paper and ink, yet "
+ "technologically advanced and open to imagination and magic.\n"
+ "Surfaces and edges of the material provide visual cues that are grounded in reality. The "
+ "use of familiar tactile attributes helps users quickly understand affordances. Yet the "
+ "flexibility of the material creates new affordances that supercede those in the physical "
+ "world, without breaking the rules of physics.\n"
+ "The fundamentals of light, surface, and movement are key to conveying how objects move, "
+ "interact, and exist in space and in relation to each other. Realistic lighting shows "
+ "seams, divides space, and indicates moving parts.\n\n"
+
+ "Bold, graphic, intentional.\n\n"
+
+ "The foundational elements of print based design typography, grids, space, scale, color, "
+ "and use of imagery guide visual treatments. These elements do far more than please the "
+ "eye. They create hierarchy, meaning, and focus. Deliberate color choices, edge to edge "
+ "imagery, large scale typography, and intentional white space create a bold and graphic "
+ "interface that immerse the user in the experience.\n"
+ "An emphasis on user actions makes core functionality immediately apparent and provides "
+ "waypoints for the user.\n\n"
+
+ "Motion provides meaning.\n\n"
+
+ "Motion respects and reinforces the user as the prime mover. Primary user actions are "
+ "inflection points that initiate motion, transforming the whole design.\n"
+ "All action takes place in a single environment. Objects are presented to the user without "
+ "breaking the continuity of experience even as they transform and reorganize.\n"
+ "Motion is meaningful and appropriate, serving to focus attention and maintain continuity. "
+ "Feedback is subtle yet clear. Transitions are efficient yet coherent.\n\n"
+
+ "3D world.\n\n"
+
+ "The material environment is a 3D space, which means all objects have x, y, and z "
+ "dimensions. The z-axis is perpendicularly aligned to the plane of the display, with the "
+ "positive z-axis extending towards the viewer. Every sheet of material occupies a single "
+ "position along the z-axis and has a standard 1dp thickness.\n"
+ "On the web, the z-axis is used for layering and not for perspective. The 3D world is "
+ "emulated by manipulating the y-axis.\n\n"
+
+ "Light and shadow.\n\n"
+
+ "Within the material environment, virtual lights illuminate the scene. Key lights create "
+ "directional shadows, while ambient light creates soft shadows from all angles.\n"
+ "Shadows in the material environment are cast by these two light sources. In Android "
+ "development, shadows occur when light sources are blocked by sheets of material at "
+ "various positions along the z-axis. On the web, shadows are depicted by manipulating the "
+ "y-axis only. The following example shows the card with a height of 6dp.\n\n"
+
+ "Resting elevation.\n\n"
+
+ "All material objects, regardless of size, have a resting elevation, or default elevation "
+ "that does not change. If an object changes elevation, it should return to its resting "
+ "elevation as soon as possible.\n\n"
+
+ "Component elevations.\n\n"
+
+ "The resting elevation for a component type is consistent across apps (e.g., FAB elevation "
+ "does not vary from 6dp in one app to 16dp in another app).\n"
+ "Components may have different resting elevations across platforms, depending on the depth "
+ "of the environment (e.g., TV has a greater depth than mobile or desktop).\n\n"
+
+ "Responsive elevation and dynamic elevation offsets.\n\n"
+
+ "Some component types have responsive elevation, meaning they change elevation in response "
+ "to user input (e.g., normal, focused, and pressed) or system events. These elevation "
+ "changes are consistently implemented using dynamic elevation offsets.\n"
+ "Dynamic elevation offsets are the goal elevation that a component moves towards, relative "
+ "to the component’s resting state. They ensure that elevation changes are consistent "
+ "across actions and component types. For example, all components that lift on press have "
+ "the same elevation change relative to their resting elevation.\n"
+ "Once the input event is completed or cancelled, the component will return to its resting "
+ "elevation.\n\n"
+
+ "Avoiding elevation interference.\n\n"
+
+ "Components with responsive elevations may encounter other components as they move between "
+ "their resting elevations and dynamic elevation offsets. Because material cannot pass "
+ "through other material, components avoid interfering with one another any number of ways, "
+ "whether on a per component basis or using the entire app layout.\n"
+ "On a component level, components can move or be removed before they cause interference. "
+ "For example, a floating action button (FAB) can disappear or move off screen before a "
+ "user picks up a card, or it can move if a snackbar appears.\n"
+ "On the layout level, design your app layout to minimize opportunities for interference. "
+ "For example, position the FAB to one side of stream of a cards so the FAB won’t interfere "
+ "when a user tries to pick up one of cards.\n\n"
+