diff --git a/app/build.gradle b/app/build.gradle
index eadc27e..03915ba 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -10,6 +10,9 @@ android {
targetSdkVersion 23
versionCode 1
versionName "1.0"
+ // Disabled for now because we're not ready to
+ // completely port over to vector drawables
+// vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
diff --git a/app/src/main/java/com/philliphsu/clock2/MainActivity.java b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
index abd86cd..6049991 100644
--- a/app/src/main/java/com/philliphsu/clock2/MainActivity.java
+++ b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
@@ -52,6 +52,11 @@ public class MainActivity extends BaseActivity {
@Bind(R.id.fab)
FloatingActionButton mFab;
+// // https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.141274xy8
+// // This is needed to load vector drawables from 23.4.0
+// static {
+// AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
+// }
@Override
protected void onCreate(Bundle savedInstanceState) {
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/BaseTimePickerDialog.java b/app/src/main/java/com/philliphsu/clock2/editalarm/BaseTimePickerDialog.java
index 0425216..5604d96 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/BaseTimePickerDialog.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/BaseTimePickerDialog.java
@@ -14,6 +14,7 @@ import butterknife.ButterKnife;
* Created by Phillip Hsu on 7/16/2016.
*/
public abstract class BaseTimePickerDialog extends BottomSheetDialogFragment {
+ private static final String TAG = "BaseTimePickerDialog";
// TODO: Consider private access, and then writing package/protected API that subclasses
// can use to interface with this field.
@@ -53,9 +54,59 @@ public abstract class BaseTimePickerDialog extends BottomSheetDialogFragment {
// getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
final View view = inflater.inflate(contentLayout(), container, false);
ButterKnife.bind(this, view);
+
+ // TODO: We could move this to onCreateDialog() if we cared.
+ //
+ // onShow() is called immediately as this DialogFragment is showing, so the
+ // FAB's animation will barely be noticeable.
+// getDialog().setOnShowListener(new DialogInterface.OnShowListener() {
+// @Override
+// public void onShow(DialogInterface dialog) {
+// Log.i(TAG, "onShow()");
+// // Animate the FAB into view
+// View v = view.findViewById(R.id.fab);
+// if (v != null) {
+// FloatingActionButton fab = (FloatingActionButton) v;
+// fab.show();
+// }
+// }
+// });
+
return view;
}
+// @Override
+// public void onResume() {
+// super.onResume();
+// final View view = getView();
+// final BottomSheetBehavior behavior = BottomSheetBehavior.from((View) view.getParent());
+// // Copy over the internal callback logic, and also implement our own
+// //
+// // This callback is set AFTER this Fragment has become visible, so is useless for what
+// // you wanted to do (show the FAB during the settling phase).
+// behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
+// @Override
+// public void onStateChanged(@NonNull View bottomSheet, int newState) {
+// Log.i(TAG, "onStateChanged(): " + newState);
+// if (newState == BottomSheetBehavior.STATE_HIDDEN) {
+// dismiss();
+// }
+// // My logic below
+// else if (newState == BottomSheetBehavior.STATE_SETTLING) {
+// View fab = view.findViewById(R.id.fab);
+// if (fab != null) {
+// ((FloatingActionButton) fab).show();
+// }
+// }
+// }
+//
+// @Override
+// public void onSlide(@NonNull View bottomSheet, float slideOffset) {
+//
+// }
+// });
+// }
+
@Override
public void onDestroyView() {
super.onDestroyView();
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/GridLayoutNumpad.java b/app/src/main/java/com/philliphsu/clock2/editalarm/GridLayoutNumpad.java
index 4fc5fb1..a40bf72 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/GridLayoutNumpad.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/GridLayoutNumpad.java
@@ -1,8 +1,10 @@
package com.philliphsu.clock2.editalarm;
import android.content.Context;
+import android.content.res.ColorStateList;
import android.support.annotation.CallSuper;
import android.support.annotation.LayoutRes;
+import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayout;
import android.util.AttributeSet;
import android.view.View;
@@ -23,6 +25,10 @@ import butterknife.OnClick;
* Unlike Numpad, this class only manages the logic for number button clicks
* and not the backspace button. However, we do provide an API for removing
* digits from the input.
+ *
+ * TODO: Is NumpadTimePicker the only subclass? If so, why do we need this
+ * superclass? If we move the contents of this class to NumpadTimePicker,
+ * the implementation of setTheme() would make more sense.
*/
public abstract class GridLayoutNumpad extends GridLayout {
// TODO: change to private?
@@ -33,6 +39,8 @@ public abstract class GridLayoutNumpad extends GridLayout {
private int mCount = 0;
private OnInputChangeListener mOnInputChangeListener;
+ ColorStateList mColors;
+
@Bind({ R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four,
R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine })
TextView[] mButtons;
@@ -64,6 +72,24 @@ public abstract class GridLayoutNumpad extends GridLayout {
init();
}
+ void setTheme(Context context, boolean themeDark) {
+ // Since the Dialog class already set the background color of its entire view tree,
+ // our background is already colored. Why did we set it in the Dialog class? Because
+ // we use margins around the numpad, and if we had instead set the background on
+ // this numpad here, the margins will not be colored. Why not use padding instead
+ // of margins? It turns out we tried that--replacing each margin attribute
+ // with the padding counterpart--but we lost the pre-21 FAB inherent bottom margin.
+
+ // The buttons are actually of type Button, but we kept references
+ // to them as TextViews... which is fine since TextView is the superclass
+ // of Button.
+ mColors = ContextCompat.getColorStateList(context,
+ themeDark? R.color.numeric_keypad_button_text_dark : R.color.numeric_keypad_button_text);
+ for (TextView b : mButtons) {
+ b.setTextColor(mColors);
+ }
+ }
+
/**
* @return the number of digits we can input
*/
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java b/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java
index 9f4443e..19b744b 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java
@@ -470,6 +470,13 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog implements
// Set the color on the FAB
// http://stackoverflow.com/a/32031019/5055032
+ // *****************************************************************************************
+ // NOTE: IF YOU DECIDE TO MOVE THE FAB AND THE HALF DAY TOGGLES TO THE GRIDSELECTORLAYOUT
+ // CLASS, YOU SHOULD CHANGE THE CONTEXT PASSED TO GridSelectorLayout#setTheme() FROM THE
+ // APPLICATION CONTEXT TO THE LOCAL CONTEXT. OTHERWISE, IT WOULD NOT BE ABLE TO RETRIEVE
+ // THE CORRECT ACCENT COLOR. WE ALREADY FACED THIS ISSUE WITH THE NUMPADTIMEPICKERDIALOG.
+ // DO A CTRL+F FOR mTimePicker.setTheme FOR THE CODE IN DISCUSSION.
+ // *****************************************************************************************
// Color in normal state
mDoneButton.setBackgroundTintList(ColorStateList.valueOf(accentColor));
// Color in pressed state. A ripple expands outwards from the point of contact throughout
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePicker.java b/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePicker.java
index 3558e0d..6de090f 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePicker.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePicker.java
@@ -1,8 +1,12 @@
package com.philliphsu.clock2.editalarm;
import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.drawable.Drawable;
import android.support.annotation.IntDef;
import android.support.design.widget.FloatingActionButton;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.graphics.drawable.DrawableCompat;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.widget.Button;
@@ -10,6 +14,8 @@ import android.widget.ImageButton;
import android.widget.TextView;
import com.philliphsu.clock2.R;
+import com.philliphsu.clock2.aospdatetimepicker.Utils;
+import com.philliphsu.clock2.util.ConversionUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -55,6 +61,11 @@ public class NumpadTimePicker extends GridLayoutNumpad {
@Bind(R.id.fab) FloatingActionButton mFab;
@Bind(R.id.backspace) ImageButton mBackspace;
+ private boolean mThemeDark;
+ private int mAccentColor;
+ private int mFabDisabledColorDark;
+ private int mFabDisabledColorLight;
+
/**
* Provides additional APIs to configure clients' display output.
*/
@@ -75,7 +86,53 @@ public class NumpadTimePicker extends GridLayoutNumpad {
super(context, attrs);
init();
}
-
+
+ @Override
+ void setTheme(Context context, boolean themeDark) {
+ super.setTheme(context, themeDark);
+ mThemeDark = themeDark;
+
+ // So, we kept the 0-9 buttons as TextViews, but here we kept
+ // the alt buttons as actual Buttons...
+ for (Button b : mAltButtons) {
+ b.setTextColor(mColors);
+ }
+
+ // Get a mutable instance of the drawable, so we only affect this instance.
+ // This is especially useful when you need to modify properties of drawables loaded from
+ // resources. By default, all drawables instances loaded from the same resource share a
+ // common state; if you modify the state of one instance, all the other instances will
+ // receive the same modification.
+ // TODO: What is the VectorDrawable counterpart for this process?
+ Drawable backspaceDrawable = mBackspace.getDrawable().mutate();
+ // Wrap drawable so that it may be used for tinting across the different
+ // API levels, via the tinting methods in this class.
+ backspaceDrawable = DrawableCompat.wrap(backspaceDrawable);
+ // Prepare the tints
+ ColorStateList colorBackspace = ContextCompat.getColorStateList(context,
+ themeDark? R.color.icon_color_dark : R.color.icon_color);
+ DrawableCompat.setTintList(backspaceDrawable, colorBackspace);
+ mBackspace.setImageDrawable(backspaceDrawable);
+
+ // TODO: What is the VectorDrawable counterpart for this process?
+ Drawable iconDrawable = mFab.getDrawable().mutate();
+ iconDrawable = DrawableCompat.wrap(iconDrawable);
+ ColorStateList colorIcon = ContextCompat.getColorStateList(context,
+ themeDark? R.color.icon_color_dark : R.color.fab_icon_color);
+ DrawableCompat.setTintList(iconDrawable, colorIcon);
+ mFab.setImageDrawable(iconDrawable);
+
+ // this.getContext() ==> default teal accent color
+ // application context ==> white
+ // The Context that was passed in is NumpadTimePickerDialog.getContext() which
+ // is probably the host Activity. I have no idea what this.getContext() returns,
+ // but its probably some internal type that isn't tied to any of our application
+ // components.
+ mAccentColor = Utils.getThemeAccentColor(context);
+ // Make sure the dark theme disabled color shows up initially
+ updateFabState();
+ }
+
@Override
public int capacity() {
return MAX_DIGITS;
@@ -255,6 +312,9 @@ public class NumpadTimePicker extends GridLayoutNumpad {
}
private void init() {
+ mFabDisabledColorDark = ContextCompat.getColor(getContext(), R.color.fab_disabled_dark);
+ mFabDisabledColorLight = ContextCompat.getColor(getContext(), R.color.fab_disabled_light);
+ // TODO: We should have the user pass in is24HourMode when they create an instance of the dialog.
if (DateFormat.is24HourFormat(getContext())) {
mAltButtons[0].setText(R.string.left_alt_24hr);
mAltButtons[1].setText(R.string.right_alt_24hr);
@@ -383,6 +443,19 @@ public class NumpadTimePicker extends GridLayoutNumpad {
private void updateFabState() {
mFab.setEnabled(checkTimeValid());
+ // Workaround for mFab.setBackgroundTintList() because I don't know how to reference the
+ // correct accent color in XML. Also because I don't want to programmatically create a
+ // ColorStateList.
+ int color;
+ // TODO: Animate elevation property "compatElevation"
+ if (mFab.isEnabled()) {
+ color = mAccentColor;
+ mFab.setCompatElevation(ConversionUtils.dpToPx(getContext(), 6));
+ } else {
+ color = mThemeDark? mFabDisabledColorDark : mFabDisabledColorLight;
+ mFab.setCompatElevation(0);
+ }
+ mFab.setBackgroundTintList(ColorStateList.valueOf(color));
}
private void updateBackspaceState() {
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePickerDialog.java b/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePickerDialog.java
index fc1ccd9..3ff9de5 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePickerDialog.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumpadTimePickerDialog.java
@@ -1,12 +1,14 @@
package com.philliphsu.clock2.editalarm;
import android.os.Bundle;
+import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.philliphsu.clock2.R;
+import com.philliphsu.clock2.aospdatetimepicker.Utils;
import butterknife.Bind;
import butterknife.OnClick;
@@ -36,6 +38,7 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
* depends on the dialog to save its state.
*/
private int[] mInputtedDigits;
+ private boolean mThemeDark;
// Don't need to keep a reference to the dismiss ImageButton
@Bind(R.id.input_time) TextView mInputField;
@@ -54,7 +57,9 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
// TODO: is24HourMode param
public static NumpadTimePickerDialog newInstance(OnTimeSetListener callback) {
NumpadTimePickerDialog ret = new NumpadTimePickerDialog();
+ // TODO: Do these in initialize()
ret.setOnTimeSetListener(callback);
+ ret.mThemeDark = false;
return ret;
}
@@ -67,6 +72,17 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
mIs24HourMode = is24HourMode;
}
+ /**
+ * Set a dark or light theme. NOTE: this will only take effect for the next onCreateView.
+ */
+ public void setThemeDark(boolean dark) {
+ mThemeDark = dark;
+ }
+
+ public boolean isThemeDark() {
+ return mThemeDark;
+ }
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -84,8 +100,24 @@ public class NumpadTimePickerDialog extends BaseTimePickerDialog
mNumpad.insertDigits(mInputtedDigits); // TOneverDO: before mNumpad.setOnInputChangeListener(this);
// Show the cursor immediately
// mInputField.requestFocus();
- // TODO: Disabled color
//updateInputText(""); // Primarily to disable 'OK'
+
+ // Prepare colors
+ int accentColor = Utils.getThemeAccentColor(getContext());
+ int lightGray = ContextCompat.getColor(getContext(), R.color.light_gray);
+ int darkGray = ContextCompat.getColor(getContext(), R.color.dark_gray);
+ int white = ContextCompat.getColor(getContext(), android.R.color.white);
+
+ // Set background color of entire view
+ view.setBackgroundColor(mThemeDark? darkGray : white);
+
+ TextView inputTime = (TextView) view.findViewById(R.id.input_time);
+ inputTime.setBackgroundColor(mThemeDark? lightGray : accentColor);
+ inputTime.setTextColor(ContextCompat.getColor(getContext(), android.R.color.white));
+
+ mNumpad.setTheme(getContext()/*DO NOT GIVE THE APPLICATION CONTEXT, OR ELSE THE NUMPAD
+ CAN'T GET THE CORRECT ACCENT COLOR*/, mThemeDark);
+
return view;
}
diff --git a/app/src/main/res/color/fab_icon_color.xml b/app/src/main/res/color/fab_icon_color.xml
new file mode 100644
index 0000000..32e32d4
--- /dev/null
+++ b/app/src/main/res/color/fab_icon_color.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/icon_color.xml b/app/src/main/res/color/icon_color.xml
new file mode 100644
index 0000000..3ff0ce5
--- /dev/null
+++ b/app/src/main/res/color/icon_color.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/icon_color_dark.xml b/app/src/main/res/color/icon_color_dark.xml
new file mode 100644
index 0000000..ce0656d
--- /dev/null
+++ b/app/src/main/res/color/icon_color_dark.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/numeric_keypad_button_text.xml b/app/src/main/res/color/numeric_keypad_button_text.xml
new file mode 100644
index 0000000..280d18b
--- /dev/null
+++ b/app/src/main/res/color/numeric_keypad_button_text.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/numeric_keypad_button_text_dark.xml b/app/src/main/res/color/numeric_keypad_button_text_dark.xml
new file mode 100644
index 0000000..c82c02f
--- /dev/null
+++ b/app/src/main/res/color/numeric_keypad_button_text_dark.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/numeric_keypad_fab_color.xml b/app/src/main/res/color/numeric_keypad_fab_color.xml
new file mode 100644
index 0000000..65fafd5
--- /dev/null
+++ b/app/src/main/res/color/numeric_keypad_fab_color.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/color/numeric_keypad_fab_color_dark.xml b/app/src/main/res/color/numeric_keypad_fab_color_dark.xml
new file mode 100644
index 0000000..f4a65f0
--- /dev/null
+++ b/app/src/main/res/color/numeric_keypad_fab_color_dark.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/ic_backspace_24dp.xml b/app/src/main/res/drawable/ic_backspace_24dp.xml
index 54ad8c1..a2da261 100644
--- a/app/src/main/res/drawable/ic_backspace_24dp.xml
+++ b/app/src/main/res/drawable/ic_backspace_24dp.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 665232e..2fcac21 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -43,7 +43,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
- android:src="@drawable/ic_add_24dp"
+ app:srcCompat="@drawable/ic_add_24dp"
android:layout_margin="@dimen/fab_margin"
android:tint="@android:color/white"/>
diff --git a/app/src/main/res/layout/content_grid_layout_numpad_dark.xml b/app/src/main/res/layout/content_grid_layout_numpad_dark.xml
new file mode 100644
index 0000000..765db8e
--- /dev/null
+++ b/app/src/main/res/layout/content_grid_layout_numpad_dark.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_numpad_time_picker.xml b/app/src/main/res/layout/content_numpad_time_picker.xml
index 130ef10..24f5e13 100644
--- a/app/src/main/res/layout/content_numpad_time_picker.xml
+++ b/app/src/main/res/layout/content_numpad_time_picker.xml
@@ -20,12 +20,13 @@
android:layout_height="wrap_content"
app:layout_gravity="center"
app:layout_column="1"
- android:src="@drawable/ic_done_24dp"
+ app:srcCompat="@drawable/ic_done_24dp"
+ app:borderWidth="0dp"
android:layout_marginBottom="@dimen/numeric_keypad_fab_bottom_margin"/>
diff --git a/app/src/main/res/layout/content_numpad_time_picker_dark.xml b/app/src/main/res/layout/content_numpad_time_picker_dark.xml
new file mode 100644
index 0000000..babc61a
--- /dev/null
+++ b/app/src/main/res/layout/content_numpad_time_picker_dark.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_time_picker_numpad.xml b/app/src/main/res/layout/dialog_time_picker_numpad.xml
index a9798ce..48b45ea 100644
--- a/app/src/main/res/layout/dialog_time_picker_numpad.xml
+++ b/app/src/main/res/layout/dialog_time_picker_numpad.xml
@@ -13,21 +13,17 @@ doesn't work. -->
android:layout_height="@dimen/numeric_keypad_output_box_height"
android:gravity="center"
android:textSize="@dimen/text_size_display_3"
- android:fontFamily="sans-serif-light"
+ android:fontFamily="sans-serif"
style="@style/TextAppearance.AppCompat"/>
-
-
diff --git a/app/src/main/res/values/aosp_datetimepicker_colors.xml b/app/src/main/res/values/aosp_datetimepicker_colors.xml
index 5cd2f36..c676fd1 100644
--- a/app/src/main/res/values/aosp_datetimepicker_colors.xml
+++ b/app/src/main/res/values/aosp_datetimepicker_colors.xml
@@ -51,4 +51,17 @@
#de000000#b3ffffff#8a000000
+ #80ffffff
+ #61000000
+
+
+ #1fffffff
+ #1f000000
+
+ #ffffffff
+ #8a000000
+
+ #4dffffff
+
+ #42000000
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 9838fff..b269b96 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -45,14 +45,20 @@
+
+