diff --git a/app/src/main/java/com/philliphsu/clock2/MainActivity.java b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
index f07cad0..abd86cd 100644
--- a/app/src/main/java/com/philliphsu/clock2/MainActivity.java
+++ b/app/src/main/java/com/philliphsu/clock2/MainActivity.java
@@ -260,8 +260,11 @@ public class MainActivity extends BaseActivity {
// has no reference to the AlarmsFragment, but it does have a reference to a
// Context (which we can cast to Activity). Thus, ExpandedAlarmViewHolder
// uses Activity#startActivityForResult().
- mSectionsPagerAdapter.getFragment(mViewPager.getCurrentItem())
- .onActivityResult(requestCode, resultCode, data);
+
+ // THIS WAS ACTUALLY A BAD IDEA, ESPECIALLY FOR TIMERSFRAGMENT. THIS ENDS UP ADDING
+ // DUPLICATE TIMERS.
+// mSectionsPagerAdapter.getFragment(mViewPager.getCurrentItem())
+// .onActivityResult(requestCode, resultCode, data);
}
@Override
diff --git a/app/src/main/java/com/philliphsu/clock2/aospdatetimepicker/Utils.java b/app/src/main/java/com/philliphsu/clock2/aospdatetimepicker/Utils.java
index 1938cb3..40b3c2a 100644
--- a/app/src/main/java/com/philliphsu/clock2/aospdatetimepicker/Utils.java
+++ b/app/src/main/java/com/philliphsu/clock2/aospdatetimepicker/Utils.java
@@ -22,10 +22,8 @@ import android.animation.PropertyValuesHolder;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Color;
import android.os.Build;
import android.support.annotation.AttrRes;
-import android.support.v4.content.ContextCompat;
import android.text.format.Time;
import android.util.TypedValue;
import android.view.View;
@@ -151,37 +149,45 @@ public class Utils {
* @param context The context to use as reference for the color
* @return the accent color of the current context
*/
- // Source from MDTP
- public static int getAccentColorFromThemeIfAvailable(Context context) {
- TypedValue typedValue = new TypedValue();
- // First, try the android:colorAccent
- if (Build.VERSION.SDK_INT >= 21) {
- context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
- return typedValue.data;
- }
- // Next, try colorAccent from support lib
- int colorAccentResId = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
- if (colorAccentResId != 0 && context.getTheme().resolveAttribute(colorAccentResId, typedValue, true)) {
- return typedValue.data;
- }
-
- return ContextCompat.getColor(context, R.color.accent_color);
+ public static int getThemeAccentColor(Context context) {
+ // Source from MDTP
+// TypedValue typedValue = new TypedValue();
+// // First, try the android:colorAccent
+// if (Build.VERSION.SDK_INT >= 21) {
+// context.getTheme().resolveAttribute(android.R.attr.colorAccent, typedValue, true);
+// return typedValue.data;
+// }
+// // Next, try colorAccent from support lib
+// int colorAccentResId = context.getResources().getIdentifier("colorAccent", "attr", context.getPackageName());
+// if (colorAccentResId != 0 && context.getTheme().resolveAttribute(colorAccentResId, typedValue, true)) {
+// return typedValue.data;
+// }
+//
+// return ContextCompat.getColor(context, R.color.accent_color);
+ return getColorFromThemeAttr(context, R.attr.colorAccent);
}
- // See http://stackoverflow.com/a/4928826/5055032
- public static int darkenColor(int color) {
- float[] hsv = new float[3];
- Color.colorToHSV(color, hsv);
- hsv[2] *= 0.8f; // value component
- return Color.HSVToColor(hsv);
+ public static int getTextColorPrimary(Context context) {
+ // http://stackoverflow.com/a/33839580/5055032
+ final TypedValue value = new TypedValue();
+ context.getTheme().resolveAttribute(android.R.attr.textColorPrimary, value, true);
+ TypedArray a = context.obtainStyledAttributes(value.data,
+ new int[] {android.R.attr.textColorPrimary});
+ final int color = a.getColor(0/*index*/, 0/*defValue*/);
+ a.recycle();
+ return color;
+ // Didn't work! Gave me white!
+// return getColorFromThemeAttr(context, android.R.attr.textColorPrimary);
}
- // See http://stackoverflow.com/a/4928826/5055032
- public static int lightenColor(int color) {
- float[] hsv = new float[3];
- Color.colorToHSV(color, hsv);
- hsv[2] = 1.0f - 0.8f * (1.0f - hsv[2]);
- return Color.HSVToColor(hsv);
+ /**
+ * @param resId The resource identifier of the desired theme attribute.
+ */
+ public static int getColorFromThemeAttr(Context context, int resId) {
+ // http://stackoverflow.com/a/28777489/5055032
+ final TypedValue value = new TypedValue();
+ context.getTheme().resolveAttribute(resId, value, true);
+ return value.data;
}
/**
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/GridSelectorLayout.java b/app/src/main/java/com/philliphsu/clock2/editalarm/GridSelectorLayout.java
new file mode 100644
index 0000000..3d464d7
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/GridSelectorLayout.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.philliphsu.clock2.editalarm;
+
+import android.content.Context;
+import android.os.Handler;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.widget.FrameLayout;
+
+/**
+ * Created by Phillip Hsu on 8/17/2016.
+ *
+ * A derivative of the AOSP datetimepicker RadialPickerLayout class.
+ */
+public class GridSelectorLayout extends FrameLayout implements NumbersGrid.OnNumberSelectedListener {
+ private static final String TAG = "GridSelectorLayout";
+
+ // Delay before auto-advancing the page, in ms.
+ // TODO: If we animate the page change, then we don't need this delay. This was
+ // my own logic, not ported from AOSP timepicker.
+ public static final int ADVANCE_PAGE_DELAY = 150;
+
+ private static final int HOUR_INDEX = NumberGridTimePickerDialog.HOUR_INDEX;
+ private static final int MINUTE_INDEX = NumberGridTimePickerDialog.MINUTE_INDEX;
+ // TODO: Rename to HALF_DAY_INDEX?
+ private static final int AMPM_INDEX = NumberGridTimePickerDialog.AMPM_INDEX;
+ private static final int HALF_DAY_1 = NumberGridTimePickerDialog.HALF_DAY_1;
+ private static final int HALF_DAY_2 = NumberGridTimePickerDialog.HALF_DAY_2;
+
+ private OnValueSelectedListener mListener;
+ private boolean mTimeInitialized;
+ private int mCurrentHoursOfDay;
+ private int mCurrentMinutes;
+ private boolean mIs24HourMode;
+ private int mCurrentItemShowing;
+
+ private HoursGrid mHoursGrid = null;
+ private TwentyFourHoursGrid m24HoursGrid = null;
+ private MinutesGrid mMinutesGrid;
+ private final Handler mHandler = new Handler();
+
+ public interface OnValueSelectedListener {
+ void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
+ }
+
+ public GridSelectorLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ // TODO: Why do we need a Context param? RadialPickerLayout does it too.
+ public void initialize(Context context, int initialHoursOfDay, int initialMinutes, boolean is24HourMode) {
+ if (mTimeInitialized) {
+ Log.e(TAG, "Time has already been initialized.");
+ return;
+ }
+
+ mIs24HourMode = is24HourMode;
+ if (is24HourMode) {
+ m24HoursGrid = new TwentyFourHoursGrid(context);
+ m24HoursGrid.initialize(this/*OnNumberSelectedListener*/);
+ addView(m24HoursGrid);
+ } else {
+ mHoursGrid = new HoursGrid(context);
+ mHoursGrid.initialize(this/*OnNumberSelectedListener*/);
+ addView(mHoursGrid);
+ }
+ mMinutesGrid = new MinutesGrid(context);
+ mMinutesGrid.initialize(this/*OnNumberSelectedListener*/);
+
+ // Initialize the currently-selected hour and minute.
+ setValueForItem(HOUR_INDEX, initialHoursOfDay);
+ setValueForItem(MINUTE_INDEX, initialMinutes);
+
+ // Record the selected values in the number grids.
+ if (!is24HourMode) {
+ initialHoursOfDay = initialHoursOfDay % 12;
+ if (initialHoursOfDay == 0) {
+ initialHoursOfDay = 12;
+ }
+ mHoursGrid.setSelection(initialHoursOfDay);
+ } else {
+ m24HoursGrid.setSelection(initialHoursOfDay);
+ }
+ mMinutesGrid.setSelection(initialMinutes);
+
+ mTimeInitialized = true;
+ }
+
+ void setTheme(Context context, boolean themeDark) {
+ // TODO: This logic needs to be in the Dialog class, since the am/pm view is contained there.
+// mAmPmView.setTheme(context, themeDark);
+
+ // TODO: These aren't doing much currently, if at all.
+ if (m24HoursGrid != null) {
+ m24HoursGrid.setTheme(context, themeDark);
+ } else if (mHoursGrid != null) {
+ mHoursGrid.setTheme(context, themeDark);
+ }
+ mMinutesGrid.setTheme(context, themeDark);
+ }
+
+ public void setTime(int hours, int minutes) {
+ setItem(HOUR_INDEX, hours);
+ setItem(MINUTE_INDEX, minutes);
+ }
+
+ /**
+ * Set either the hour or the minute. Will set the internal value, and set the selection.
+ */
+ private void setItem(int index, int value) {
+ if (index == HOUR_INDEX) {
+ setValueForItem(HOUR_INDEX, value);
+ if (mIs24HourMode) {
+ m24HoursGrid.setSelection(value);
+ } else {
+ mHoursGrid.setSelection(value);
+ }
+ } else if (index == MINUTE_INDEX) {
+ setValueForItem(MINUTE_INDEX, value);
+ mMinutesGrid.setSelection(value);
+ }
+ }
+
+ public void setOnValueSelectedListener(OnValueSelectedListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * Get the item (hours or minutes) that is currently showing.
+ */
+ public int getCurrentItemShowing() {
+ if (mCurrentItemShowing != HOUR_INDEX && mCurrentItemShowing != MINUTE_INDEX) {
+ Log.e(TAG, "Current item showing was unfortunately set to "+mCurrentItemShowing);
+ return -1;
+ }
+ return mCurrentItemShowing;
+ }
+
+ /**
+ * Set either minutes or hours as showing.
+ * @param animate True to animate the transition, false to show with no animation.
+ */
+ public void setCurrentItemShowing(int index, boolean animate) {
+ if (index != HOUR_INDEX && index != MINUTE_INDEX) {
+ Log.e(TAG, "TimePicker does not support view at index "+index);
+ return;
+ }
+
+ int lastIndex = getCurrentItemShowing();
+ mCurrentItemShowing = index;
+
+ if (index != lastIndex) {
+ removeViewAt(0); // We could also call removeAllViews(), since we only have one child.
+ // We already verified that the index is either HOUR_INDEX or MINUTE_INDEX
+ addView(index == HOUR_INDEX ?
+ (mIs24HourMode ? m24HoursGrid : mHoursGrid)
+ : mMinutesGrid);
+ }
+ }
+
+ // TODO: The Dialog should be telling us that AM/PM was selected, via setAmOrPm().
+// @Override
+// public void onAmPmSelected(int amOrPm) {
+// setValueForItem(AMPM_INDEX, amOrPm);
+// mListener.onValueSelected(AMPM_INDEX, amOrPm, false);
+// }
+
+ @Override
+ public void onNumberSelected(int number) {
+ if (getCurrentItemShowing() == HOUR_INDEX && !mIs24HourMode) {
+ // Change the value before passing it through the callback
+ int amOrPm = getIsCurrentlyAmOrPm();
+ if (amOrPm == HALF_DAY_1 && number == 12) {
+ number = 0;
+ } else if (amOrPm == HALF_DAY_2 && number != 12) {
+ number += 12;
+ }
+ }
+
+// final int value = number;
+// mHandler.postDelayed(new Runnable() {
+// @Override
+// public void run() {
+// mListener.onValueSelected(HOUR_INDEX, value, true);
+// }
+// }, ADVANCE_PAGE_DELAY);
+// mListener.onValueSelected(HOUR_INDEX, value, true);
+// } else {
+// mListener.onValueSelected(getCurrentItemShowing(), number, false);
+// }
+ setValueForItem(getCurrentItemShowing(), number);
+ mListener.onValueSelected(getCurrentItemShowing(), number,
+ true/*autoAdvance, not considered for MINUTE_INDEX*/);
+ }
+
+ public int getHours() {
+ return mCurrentHoursOfDay;
+ }
+
+ public int getMinutes() {
+ return mCurrentMinutes;
+ }
+
+ /**
+ * If the hours are showing, return the current hour. If the minutes are showing, return the
+ * current minute.
+ */
+ private int getCurrentlyShowingValue() {
+ int currentIndex = getCurrentItemShowing();
+ if (currentIndex == HOUR_INDEX) {
+ return mCurrentHoursOfDay;
+ } else if (currentIndex == MINUTE_INDEX) {
+ return mCurrentMinutes;
+ } else {
+ return -1;
+ }
+ }
+
+ public int getIsCurrentlyAmOrPm() {
+ if (mCurrentHoursOfDay < 12) {
+ return HALF_DAY_1;
+ } else if (mCurrentHoursOfDay < 24) {
+ return HALF_DAY_2;
+ }
+ return -1;
+ }
+
+ /**
+ * Set the internal as either AM or PM.
+ */
+ // TODO: Rename to setHalfDay
+ public void setAmOrPm(int amOrPm) {
+ final int initialHalfDay = getIsCurrentlyAmOrPm();
+ setValueForItem(AMPM_INDEX, amOrPm);
+ if (amOrPm != initialHalfDay
+ && mIs24HourMode
+// && getCurrentItemShowing() == HOUR_INDEX
+ && m24HoursGrid != null) {
+ m24HoursGrid.swapTexts();
+ mListener.onValueSelected(HOUR_INDEX, mCurrentHoursOfDay, false);
+ }
+ }
+
+ /**
+ * Set the internal value for the hour, minute, or AM/PM.
+ */
+ private void setValueForItem(int index, int value) {
+ if (index == HOUR_INDEX) {
+ mCurrentHoursOfDay = value;
+ } else if (index == MINUTE_INDEX){
+ mCurrentMinutes = value;
+ } else if (index == AMPM_INDEX) {
+ if (value == HALF_DAY_1) {
+ mCurrentHoursOfDay = mCurrentHoursOfDay % 12;
+ } else if (value == HALF_DAY_2) {
+ mCurrentHoursOfDay = (mCurrentHoursOfDay % 12) + 12;
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/HoursGrid.java b/app/src/main/java/com/philliphsu/clock2/editalarm/HoursGrid.java
new file mode 100644
index 0000000..372b916
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/HoursGrid.java
@@ -0,0 +1,26 @@
+package com.philliphsu.clock2.editalarm;
+
+import android.content.Context;
+
+import com.philliphsu.clock2.R;
+
+/**
+ * Created by Phillip Hsu on 8/17/2016.
+ */
+public class HoursGrid extends NumbersGrid {
+
+ public HoursGrid(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected int contentLayout() {
+ return R.layout.content_hours_grid;
+ }
+
+ @Override
+ protected int indexOfDefaultValue() {
+ // This is the index of number 12.
+ return getChildCount() - 1;
+ }
+}
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/MinutesGrid.java b/app/src/main/java/com/philliphsu/clock2/editalarm/MinutesGrid.java
new file mode 100644
index 0000000..17dc954
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/MinutesGrid.java
@@ -0,0 +1,71 @@
+package com.philliphsu.clock2.editalarm;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.philliphsu.clock2.R;
+
+/**
+ * Created by Phillip Hsu on 8/17/2016.
+ */
+public class MinutesGrid extends NumbersGrid {
+ private static final String TAG = "MinutesGrid";
+
+ private final ImageButton mMinusButton;
+ private final ImageButton mPlusButton;
+
+ public MinutesGrid(Context context) {
+ super(context);
+ mMinusButton = (ImageButton) getChildAt(getChildCount() - 2);
+ mPlusButton = (ImageButton) getChildAt(getChildCount() - 1);
+ // We're not doing method binding because we don't have IDs set on these buttons.
+ mMinusButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int value = getSelection() - 1;
+ if (value < 0)
+ value = 59;
+ setIndicator(value);
+ setSelection(value);
+ mSelectionListener.onNumberSelected(value);
+ }
+ });
+ mPlusButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ int value = getSelection() + 1;
+ if (value == 60)
+ value = 0;
+ setIndicator(value);
+ setSelection(value);
+ mSelectionListener.onNumberSelected(value);
+ }
+ });
+ }
+
+ @Override
+ protected int contentLayout() {
+ return R.layout.content_minutes_grid;
+ }
+
+ @Override
+ void setTheme(Context context, boolean themeDark) {
+ super.setTheme(context, themeDark);
+ mMinusButton.setImageResource(themeDark? R.drawable.ic_minus_circle_dark_24dp : R.drawable.ic_minus_circle_24dp);
+ mPlusButton.setImageResource(themeDark? R.drawable.ic_add_circle_dark_24dp : R.drawable.ic_add_circle_24dp);
+ }
+
+ /**
+ * Helper method for minute tuners to set the indicator.
+ * @param value the new value set by the minute tuners
+ */
+ private void setIndicator(int value) {
+ clearIndicator();
+ if (value % 5 == 0) {
+ // The new value is one of the predetermined minute values
+ int positionOfValue = value / 5;
+ setIndicator(getChildAt(positionOfValue));
+ }
+ }
+}
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 ddf3f58..ba13460 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumberGridTimePickerDialog.java
@@ -18,11 +18,10 @@ package com.philliphsu.clock2.editalarm;
import android.animation.ObjectAnimator;
import android.app.ActionBar.LayoutParams;
+import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.os.Bundle;
-import android.os.Handler;
import android.support.design.widget.FloatingActionButton;
-import android.support.v7.widget.GridLayout;
import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
@@ -36,6 +35,7 @@ import android.widget.TextView;
import com.philliphsu.clock2.R;
import com.philliphsu.clock2.aospdatetimepicker.Utils;
+import com.philliphsu.clock2.editalarm.GridSelectorLayout.OnValueSelectedListener;
import java.text.DateFormatSymbols;
import java.util.ArrayList;
@@ -53,8 +53,12 @@ import static com.philliphsu.clock2.util.ConversionUtils.dpToPx;
/**
* Dialog to set a time.
+ *
+ * A derivative of the AOSP datetimepicker TimePickerDialog class.
+ *
+ * TODO: Rename to GridSelectorTimePickerDialog
*/
-public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFragment implements OnValueSelectedListener*/{
+public class NumberGridTimePickerDialog extends BaseTimePickerDialog implements OnValueSelectedListener {
private static final String TAG = "TimePickerDialog";
private static final String KEY_HOUR_OF_DAY = "hour_of_day";
@@ -68,15 +72,16 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
public static final int HOUR_INDEX = 0;
public static final int MINUTE_INDEX = 1;
// NOT a real index for the purpose of what's showing.
+ // TODO: Rename to HALF_DAY_INDEX?
public static final int AMPM_INDEX = 2;
// Also NOT a real index, just used for keyboard mode.
public static final int ENABLE_PICKER_INDEX = 3;
/**
- * TODO: (Me) Use HALF_DAY_1 instead
+ * TODO: Use HALF_DAY_1 instead
*/
public static final int AM = 0;
/**
- * TODO: (Me) Use HALF_DAY_2 instead
+ * TODO: Use HALF_DAY_2 instead
*/
public static final int PM = 1;
@@ -93,7 +98,7 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
private TextView mMinuteSpaceView;
private TextView mAmPmTextView;
private View mAmPmHitspace;
-// private RadialPickerLayout mTimePicker;
+ private GridSelectorLayout mTimePicker;
private int mSelectedColor;
private int mUnselectedColor;
@@ -123,27 +128,18 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
private String mSelectMinutes;
// ====================================== MY STUFF =============================================
- private static final int[] HOURS_12 = {1,2,3,4,5,6,7,8,9,10,11,12};
- private static final int[] HOURS_24_HALF_DAY_1 = {0,1,2,3,4,5,6,7,8,9,10,11};
- private static final int[] HOURS_24_HALF_DAY_2 = {12,13,14,15,16,17,18,19,20,21,22,23};
- private static final int[] MINUTES = {0,5,10,15,20,25,30,35,40,45,50,55};
- // The delay in ms before a OnLongClick on a TwentyFourHourGridItem defers to OnClick
- private static final int LONG_CLICK_RESULT_LEEWAY = 150;
// The padding in dp for the half day icon compound drawable
public static final int HALF_DAY_ICON_PADDING = 8;
- // TODO: Private?
// Describes both AM/PM in the 12-hour clock and the half-days of the 24-hour clock.
+ // TODO: Use the *values* of AM and PM instead.
public static final int HALF_DAY_1 = AM;
public static final int HALF_DAY_2 = PM;
- private int mCurrentIndex = HOUR_INDEX;
- private int mSelectedHalfDay = HALF_DAY_1;
- private int mSelectedHourOfDay;
- private int mSelectedMinute;
- private Handler mHandler;
-
- @Bind(R.id.grid_layout) GridLayout mGridLayout;
+ // TODO: Consider moving these to GridSelectorLayout?
+ // TODO: Consider using findViewById() instead. This could be useful if you plan on
+ // releasing a library with this timepicker, because then we have no dependence on
+ // other third party libraries.
@Bind(R.id.fab) FloatingActionButton mDoneButton;
// These are currently defined as Buttons in the dialog's layout,
// but we refer to them as TextViews to save an extra refactoring
@@ -156,213 +152,70 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
return R.layout.dialog_time_picker_number_grid;
}
- private void setNumberTexts() {
- if (mCurrentIndex != HOUR_INDEX && mCurrentIndex != MINUTE_INDEX) {
- Log.e(TAG, "TimePicker does not support view at index "+mCurrentIndex);
- return;
- }
-
- // Set the appropriate texts on each view
- for (int i = 0; i < mGridLayout.getChildCount(); i++) {
- View v = mGridLayout.getChildAt(i);
- if (mCurrentIndex == MINUTE_INDEX || mCurrentIndex == HOUR_INDEX && !mIs24HourMode) {
- if (!(v instanceof TextView))
- return; // Reached the ImageButtons
- TextView tv = (TextView) v;
- tv.setText(mCurrentIndex == MINUTE_INDEX
- ? String.format("%02d", MINUTES[i])
- : String.valueOf(HOURS_12[i]));
- } else if (mCurrentIndex == HOUR_INDEX && mIs24HourMode) {
- TwentyFourHourGridItem item = (TwentyFourHourGridItem) v;
- String s1 = String.format("%02d", HOURS_24_HALF_DAY_1[i]);
- String s2 = String.valueOf(HOURS_24_HALF_DAY_2[i]);
- if (mSelectedHalfDay == HALF_DAY_1) {
- item.setPrimaryText(s1);
- item.setSecondaryText(s2);
- } else if (mSelectedHalfDay == HALF_DAY_2) {
- item.setPrimaryText(s2);
- item.setSecondaryText(s1);
- } else {
- Log.e(TAG, "mSelectedHalfDay = " + mSelectedHalfDay + "?");
- }
- }
- }
- }
-
- // TODO: boolean animate param???
- private void setCurrentItemShowing(int index) {
- if (index != HOUR_INDEX && index != MINUTE_INDEX) {
- Log.e(TAG, "TimePicker does not support view at index "+index);
- return;
- }
-
- int lastIndex = mCurrentIndex;
- mCurrentIndex = index;
-
- if (index != lastIndex) {
- if (mIs24HourMode) {
- // Hours layout and normal layout use different Views for their grid items,
- // so we have to start fresh.
- mGridLayout.removeAllViews();
- int layout = index == HOUR_INDEX ? R.layout.content_24h_number_grid : R.layout.content_number_grid;
- View.inflate(getActivity(), layout, mGridLayout);
-
- // TOneverDO: call after inflating minute tuner buttons
- setNumberTexts();
- setClickListenersOnButtons();
- //end TOneverDO
- } else {
- if (index == HOUR_INDEX) {
- // Remove the minute tuners
- mGridLayout.removeViews(mGridLayout.getChildCount() - 2, 2);
- }
- // We can reuse the existing child Views, just change the texts.
- // They already have the click listener set.
- setNumberTexts();
- }
-
- if (index == MINUTE_INDEX) {
- createMinuteTuners();
- }
- }
- }
-
- private void setClickListenersOnButtons() {
- for (int i = 0; i < mGridLayout.getChildCount(); i++) {
- // TODO: Consider leaving out the minute tuner buttons
- View v = mGridLayout.getChildAt(i);
- v.setOnClickListener(mOnNumberClickListener);
- if (v instanceof TwentyFourHourGridItem) {
- v.setOnLongClickListener(mOn24HourItemLongClickListener);
- }
- }
- }
-
@OnClick({ R.id.half_day_toggle_1, R.id.half_day_toggle_2 })
void onHalfDayToggleClick(View v) {
- int halfDay = v == mLeftHalfDayToggle ? HALF_DAY_1 : HALF_DAY_2;
- if (halfDay != mSelectedHalfDay) {
- toggleHalfDay();
+ final int halfDay = v == mLeftHalfDayToggle ? HALF_DAY_1 : HALF_DAY_2;
+ if (halfDay != mTimePicker.getIsCurrentlyAmOrPm()) {
+// if (currentHalfDay == HALF_DAY_1) {
+// currentHalfDay = HALF_DAY_2;
+// } else if (currentHalfDay == HALF_DAY_2) {
+// currentHalfDay = HALF_DAY_1;
+// }
+ updateAmPmDisplay(halfDay);
+ mTimePicker.setAmOrPm(halfDay);
}
}
- private void toggleHalfDay() {
+// private void toggleHalfDay() {
// int amOrPm = mTimePicker.getIsCurrentlyAmOrPm();
- int amOrPm = mSelectedHalfDay;
- // TODO: Use HALF_DAY_1 and 2 instead
- if (amOrPm == AM) {
- amOrPm = PM;
- } else if (amOrPm == PM){
- amOrPm = AM;
- }
- updateAmPmDisplay(amOrPm);
+// // TODO: Use HALF_DAY_1 and 2 instead
+// if (amOrPm == AM) {
+// amOrPm = PM;
+// } else if (amOrPm == PM){
+// amOrPm = AM;
+// }
+// updateAmPmDisplay(amOrPm);
// mTimePicker.setAmOrPm(amOrPm);
- mSelectedHalfDay = amOrPm;
+// // TODO: Pretty sure we don't need this
+//// mSelectedHalfDay = amOrPm;
+//
+// // TODO: Verify the corresponding TwentyFourHourGridItem retains its indicator
+// // TODO: Don't use mSelectedHourOfDay anymore. Use mTimePicker.getHours()?
+// if (amOrPm == HALF_DAY_1) {
+// mSelectedHourOfDay %= 12;
+// } else if (amOrPm == HALF_DAY_2) {
+// mSelectedHourOfDay = (mSelectedHourOfDay % 12) + 12;
+// }
+// // Updates the header display
+// onValueSelected(HOUR_INDEX, mSelectedHourOfDay, false);
+// }
- if (mIs24HourMode) {
- if (mCurrentIndex == HOUR_INDEX) {
- for (int i = 0; i < mGridLayout.getChildCount(); i++) {
- View v = mGridLayout.getChildAt(i);
- ((TwentyFourHourGridItem) v).swapTexts();
- }
- }
- }
-
- // TODO: Verify the corresponding TwentyFourHourGridItem retains its indicator
- if (amOrPm == HALF_DAY_1) {
- mSelectedHourOfDay %= 12;
- } else if (amOrPm == HALF_DAY_2) {
- mSelectedHourOfDay = (mSelectedHourOfDay % 12) + 12;
- }
- onValueSelected(HOUR_INDEX, mSelectedHourOfDay, false);
- }
-
- private void createMinuteTuners() {
- // https://android-developers.blogspot.com/2009/03/android-layout-tricks-3-optimize-by.html
- // "When inflating a layout starting with a , you *must* specify a parent ViewGroup
- // and you must set attachToRoot to true (see the documentation of the LayoutInflater#inflate() method)"
- // Note that by passing in a non-null parent, this will pass in true for attachToRoot.
- View.inflate(getActivity(), R.layout.content_number_grid_minute_tuners, mGridLayout);
- int childCount = mGridLayout.getChildCount();
- // The tuner buttons are always the last two children in the grid
- mGridLayout.getChildAt(childCount - 2).setOnClickListener(mOnDecrementMinuteListener);
- mGridLayout.getChildAt(childCount - 1).setOnClickListener(mOnIncrementMinuteListener);
- }
-
- // TODO: Break this into two OnClickListeners instead--one for normal TextViews and
- // the other for TwentyFourHourGridItem.
- // TODO: Set the indicator
- private final OnClickListener mOnNumberClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- String number;
- if (v instanceof TextView) {
- number = ((TextView) v).getText().toString();
- } else if (v instanceof TwentyFourHourGridItem) {
- number = ((TwentyFourHourGridItem) v).getPrimaryText().toString();
- } else {
- Log.e(TAG, "TimePicker does not support button type " + v.getClass().getName());
- return;
- }
- int value = Integer.parseInt(number);
- if (mCurrentIndex == HOUR_INDEX && !mIs24HourMode) {
- if (value == 12 && mSelectedHalfDay == HALF_DAY_1) {
- value = 0;
- } else if (value != 12 && mSelectedHalfDay == HALF_DAY_2) {
- value += 12;
- }
- }
- onValueSelected(mCurrentIndex, value, true);
- }
- };
-
- private final View.OnLongClickListener mOn24HourItemLongClickListener = new View.OnLongClickListener() {
- @Override
- public boolean onLongClick(final View v) {
- // TODO: Do we need this if we already check this before setting the listener on the view?
- if (!(v instanceof TwentyFourHourGridItem))
- return false;
- toggleHalfDay();
- mOnNumberClickListener.onClick(v);
- return true;
- }
- };
-
- private final OnClickListener mOnIncrementMinuteListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- // Don't need to check for minute overflow, because setMinute()
- // sets minute to 0 if we pass in 60
- onValueSelected(MINUTE_INDEX, mSelectedMinute + 1, false);
- }
- };
-
- private final OnClickListener mOnDecrementMinuteListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- int value = mSelectedMinute - 1;
- if (value < 0)
- value = 59;
- onValueSelected(MINUTE_INDEX, value, false);
- }
- };
+// private final OnClickListener mOnNumberClickListener = new OnClickListener() {
+// @Override
+// public void onClick(View v) {
+// String number;
+// if (v instanceof TextView) {
+// number = ((TextView) v).getText().toString();
+// } else if (v instanceof TwentyFourHourGridItem) {
+// number = ((TwentyFourHourGridItem) v).getPrimaryText().toString();
+// } else {
+// Log.e(TAG, "TimePicker does not support button type " + v.getClass().getName());
+// return;
+// }
+// int value = Integer.parseInt(number);
+// if (mCurrentIndex == HOUR_INDEX && !mIs24HourMode) {
+// if (value == 12 && mSelectedHalfDay == HALF_DAY_1) {
+// value = 0;
+// } else if (value != 12 && mSelectedHalfDay == HALF_DAY_2) {
+// value += 12;
+// }
+// }
+// onValueSelected(mCurrentIndex, value, true);
+// }
+// };
// =============================================================================================
-// /**
-// * The callback interface used to indicate the user is done filling in
-// * the time (they clicked on the 'Set' button).
-// */
-// public interface OnTimeSetListener {
-//
-// /**
-// * @param view The view associated with this listener.
-// * @param hourOfDay The hour that was set.
-// * @param minute The minute that was set.
-// */
-// void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute);
-// }
-
public NumberGridTimePickerDialog() {
// Empty constructor required for dialog fragment.
}
@@ -379,23 +232,6 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
return ret;
}
- /**
- * @param timeFieldIndex The index representing the time field whose values, ranging from its natural
- * lower and upper limits, will be presented as choices in the GridLayout
- * contained in this dialog's layout. Must be one of {@link #HOUR_INDEX}
- * or {@link #MINUTE_INDEX}. TODO: Why do we need this?
- * @param initialHalfDay The half-day, a.k.a. AM/PM for 12-hour time, that this picker should be
- * initialized to. Must be one of {@link #HALF_DAY_1} or {@link #HALF_DAY_2}.
- * TODO: Why do we need this?
- */
- @Deprecated
- public static NumberGridTimePickerDialog newInstance(int timeFieldIndex, int initialHalfDay) {
- NumberGridTimePickerDialog dialog = new NumberGridTimePickerDialog();
- dialog.mCurrentIndex = timeFieldIndex;
- dialog.mSelectedHalfDay = initialHalfDay;
- return dialog;
- }
-
public void initialize(OnTimeSetListener callback,
int hourOfDay, int minute, boolean is24HourMode) {
mCallback = callback; // TODO: Use setOnTimeSetListener() instead?
@@ -405,8 +241,6 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
mIs24HourMode = is24HourMode;
mInKbMode = false;
mThemeDark = false;
-
- mSelectedHalfDay = hourOfDay < 12 ? HALF_DAY_1 : HALF_DAY_2;
}
/**
@@ -420,6 +254,7 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
return mThemeDark;
}
+ // Defined as final in our base class.
// public void setOnTimeSetListener(OnTimeSetListener callback) {
// mCallback = callback;
// }
@@ -433,16 +268,13 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- // The Activity is created at this point
-// mIs24HourMode = DateFormat.is24HourFormat(getActivity());
- mHandler = new Handler();
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_HOUR_OF_DAY)
&& savedInstanceState.containsKey(KEY_MINUTE)
&& savedInstanceState.containsKey(KEY_IS_24_HOUR_VIEW)) {
mInitialHourOfDay = savedInstanceState.getInt(KEY_HOUR_OF_DAY);
mInitialMinute = savedInstanceState.getInt(KEY_MINUTE);
mIs24HourMode = savedInstanceState.getBoolean(KEY_IS_24_HOUR_VIEW);
-// mInKbMode = savedInstanceState.getBoolean(KEY_IN_KB_MODE);
+ mInKbMode = savedInstanceState.getBoolean(KEY_IN_KB_MODE);
mThemeDark = savedInstanceState.getBoolean(KEY_DARK_THEME);
}
}
@@ -458,23 +290,16 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
View view = super.onCreateView(inflater, container, savedInstanceState);
- // Inflate the buttons into the grid
- int layout = mIs24HourMode ? R.layout.content_24h_number_grid : R.layout.content_number_grid;
- View.inflate(getActivity(), layout, mGridLayout);
- setNumberTexts();
- setClickListenersOnButtons();
- if (mCurrentIndex == MINUTE_INDEX) {
- createMinuteTuners();
- }
-
Resources res = getResources();
mHourPickerDescription = res.getString(R.string.hour_picker_description);
mSelectHours = res.getString(R.string.select_hours);
mMinutePickerDescription = res.getString(R.string.minute_picker_description);
mSelectMinutes = res.getString(R.string.select_minutes);
- mSelectedColor = res.getColor(mThemeDark? R.color.red : R.color.blue);
- mUnselectedColor =
- res.getColor(mThemeDark? android.R.color.white : R.color.numbers_text_color);
+// mSelectedColor = res.getColor(mThemeDark? R.color.red : R.color.blue);
+// mUnselectedColor =
+// res.getColor(mThemeDark? android.R.color.white : R.color.numbers_text_color);
+ mSelectedColor = res.getColor(android.R.color.white);
+ mUnselectedColor = res.getColor(R.color.unselected_color);
mHourView = (TextView) view.findViewById(R.id.hours);
// mHourView.setOnKeyListener(keyboardListener);
@@ -506,12 +331,11 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
}
// mHapticFeedbackController = new HapticFeedbackController(getActivity());
-
-// mTimePicker = (RadialPickerLayout) view.findViewById(R.id.time_picker);
-// mTimePicker.setOnValueSelectedListener(this);
+ mTimePicker = (GridSelectorLayout) view.findViewById(R.id.time_picker);
+ mTimePicker.setOnValueSelectedListener(this);
// mTimePicker.setOnKeyListener(keyboardListener);
-// mTimePicker.initialize(getActivity(), mHapticFeedbackController, mInitialHourOfDay,
-// mInitialMinute, mIs24HourMode);
+ mTimePicker.initialize(getActivity(), /*mHapticFeedbackController,*/ mInitialHourOfDay,
+ mInitialMinute, mIs24HourMode);
int currentItemShowing = HOUR_INDEX;
if (savedInstanceState != null &&
@@ -519,7 +343,7 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
currentItemShowing = savedInstanceState.getInt(KEY_CURRENT_ITEM_SHOWING);
}
setCurrentItemShowing(currentItemShowing, false, true, true);
-// mTimePicker.invalidate();
+ mTimePicker.invalidate();
mHourView.setOnClickListener(new OnClickListener() {
@Override
@@ -537,6 +361,7 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
});
// mDoneButton = (TextView) view.findViewById(R.id.done_button);
+ // This is our FAB.
mDoneButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -545,12 +370,8 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
} else {
tryVibrate();
}
- Log.i(TAG, String.format("Selected time is %02d:%02d", mSelectedHourOfDay, mSelectedMinute));
if (mCallback != null) {
-// mCallback.onTimeSet(mTimePicker, mTimePicker.getHours(), mTimePicker.getMinutes());
- // I don't think the listener actually uses the first param passed back,
- // so passing null is fine.
- mCallback.onTimeSet(null, mSelectedHourOfDay, mSelectedMinute);
+ mCallback.onTimeSet(mTimePicker, mTimePicker.getHours(), mTimePicker.getMinutes());
}
dismiss();
}
@@ -574,15 +395,14 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
@Override
public void onClick(View v) {
tryVibrate();
-// int amOrPm = mTimePicker.getIsCurrentlyAmOrPm();
-// if (amOrPm == AM) {
-// amOrPm = PM;
-// } else if (amOrPm == PM){
-// amOrPm = AM;
-// }
-// updateAmPmDisplay(amOrPm);
-// mTimePicker.setAmOrPm(amOrPm);
- toggleHalfDay();
+ int amOrPm = mTimePicker.getIsCurrentlyAmOrPm();
+ if (amOrPm == AM) {
+ amOrPm = PM;
+ } else if (amOrPm == PM){
+ amOrPm = AM;
+ }
+ updateAmPmDisplay(amOrPm);
+ mTimePicker.setAmOrPm(amOrPm);
}
});
}
@@ -606,30 +426,44 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
}
// Set the theme at the end so that the initialize()s above don't counteract the theme.
-// mTimePicker.setTheme(getActivity().getApplicationContext(), mThemeDark);
+ mTimePicker.setTheme(getActivity().getApplicationContext(), mThemeDark);
// Prepare some colors to use.
int white = res.getColor(android.R.color.white);
-// int circleBackground = res.getColor(R.color.circle_background);
-// int line = res.getColor(R.color.line_background);
+ int circleBackground = res.getColor(R.color.circle_background);
+ int line = res.getColor(R.color.line_background);
int timeDisplay = res.getColor(R.color.numbers_text_color);
+ // TODO: Port the AOSP timepicker files that contain these resources.
// ColorStateList doneTextColor = res.getColorStateList(R.color.done_text_color);
// int doneBackground = R.drawable.done_background_color;
int darkGray = res.getColor(R.color.dark_gray);
-// int lightGray = res.getColor(R.color.light_gray);
-// int darkLine = res.getColor(R.color.line_dark);
+ int lightGray = res.getColor(R.color.light_gray);
+ int darkLine = res.getColor(R.color.line_dark);
+ // TODO: Port the AOSP timepicker files that contain these resources.
// ColorStateList darkDoneTextColor = res.getColorStateList(R.color.done_text_color_dark);
// int darkDoneBackground = R.drawable.done_background_color_dark;
+ // My colors
+ int accentColor = Utils.getThemeAccentColor(getContext());
+
// Set the colors for each view based on the theme.
- view.findViewById(R.id.time_display_background).setBackgroundColor(mThemeDark? darkGray : white);
- view.findViewById(R.id.time_display).setBackgroundColor(mThemeDark? darkGray : white);
- ((TextView) view.findViewById(R.id.separator)).setTextColor(mThemeDark? white : timeDisplay);
- ((TextView) view.findViewById(R.id.ampm_label)).setTextColor(mThemeDark? white : timeDisplay);
+ view.findViewById(R.id.time_display_background).setBackgroundColor(mThemeDark? lightGray : accentColor);
+ view.findViewById(R.id.time_display).setBackgroundColor(mThemeDark? lightGray : accentColor);
+ ((TextView) view.findViewById(R.id.separator)).setTextColor(/*mThemeDark? white : timeDisplay*/mUnselectedColor);
+ ((TextView) view.findViewById(R.id.ampm_label)).setTextColor(/*mThemeDark? white : timeDisplay*/mUnselectedColor);
// view.findViewById(R.id.line).setBackgroundColor(mThemeDark? darkLine : line);
// mDoneButton.setTextColor(mThemeDark? darkDoneTextColor : doneTextColor);
-// mTimePicker.setBackgroundColor(mThemeDark? lightGray : circleBackground);
+ // The AOSP timepicker originally uses these colors for the CircleView
+ mTimePicker.setBackgroundColor(mThemeDark? /*lightGray : circleBackground*/ darkGray : white);
// mDoneButton.setBackgroundResource(mThemeDark? darkDoneBackground : doneBackground);
+ // http://stackoverflow.com/a/32031019/5055032
+ // Color in normal state
+ mDoneButton.setBackgroundTintList(ColorStateList.valueOf(accentColor));
+ // Color in pressed state. A ripple expands outwards from the point of contact throughout
+ // the fab when it is long pressed.
+// mDoneButton.setRippleColor(/*your color here*/);
+ view.findViewById(R.id.half_day_toggles).setBackgroundColor(mThemeDark? /*lightGray : circleBackground*/ darkGray : white);
+
return view;
}
@@ -652,11 +486,11 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
private void updateAmPmDisplay(int amOrPm) {
if (amOrPm == AM) {
mAmPmTextView.setText(mAmText);
-// Utils.tryAccessibilityAnnounce(mTimePicker, mAmText);
+ Utils.tryAccessibilityAnnounce(mTimePicker, mAmText);
mAmPmHitspace.setContentDescription(mAmText);
} else if (amOrPm == PM){
mAmPmTextView.setText(mPmText);
-// Utils.tryAccessibilityAnnounce(mTimePicker, mPmText);
+ Utils.tryAccessibilityAnnounce(mTimePicker, mPmText);
mAmPmHitspace.setContentDescription(mPmText);
} else {
mAmPmTextView.setText(mDoublePlaceholderText);
@@ -665,28 +499,23 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
@Override
public void onSaveInstanceState(Bundle outState) {
-// if (mTimePicker != null) {
-// outState.putInt(KEY_HOUR_OF_DAY, mTimePicker.getHours());
-// outState.putInt(KEY_MINUTE, mTimePicker.getMinutes());
-// outState.putBoolean(KEY_IS_24_HOUR_VIEW, mIs24HourMode);
-// outState.putInt(KEY_CURRENT_ITEM_SHOWING, mTimePicker.getCurrentItemShowing());
-// outState.putBoolean(KEY_IN_KB_MODE, mInKbMode);
-// if (mInKbMode) {
-// outState.putIntegerArrayList(KEY_TYPED_TIMES, mTypedTimes);
-// }
-// outState.putBoolean(KEY_DARK_THEME, mThemeDark);
-// }
- outState.putInt(KEY_HOUR_OF_DAY, mSelectedHourOfDay);
- outState.putInt(KEY_MINUTE, mSelectedMinute);
- outState.putBoolean(KEY_IS_24_HOUR_VIEW, mIs24HourMode);
- outState.putInt(KEY_CURRENT_ITEM_SHOWING, mCurrentIndex);
- outState.putBoolean(KEY_DARK_THEME, mThemeDark);
+ if (mTimePicker != null) {
+ outState.putInt(KEY_HOUR_OF_DAY, mTimePicker.getHours());
+ outState.putInt(KEY_MINUTE, mTimePicker.getMinutes());
+ outState.putBoolean(KEY_IS_24_HOUR_VIEW, mIs24HourMode);
+ outState.putInt(KEY_CURRENT_ITEM_SHOWING, mTimePicker.getCurrentItemShowing());
+ outState.putBoolean(KEY_IN_KB_MODE, mInKbMode);
+ if (mInKbMode) {
+ outState.putIntegerArrayList(KEY_TYPED_TIMES, mTypedTimes);
+ }
+ outState.putBoolean(KEY_DARK_THEME, mThemeDark);
+ }
}
-// /**
-// * Called by the picker for updating the header display.
-// */
-// @Override
+ /**
+ * Called by the picker for updating the header display.
+ */
+ @Override
public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) {
if (pickerIndex == HOUR_INDEX) {
setHour(newValue, false);
@@ -695,13 +524,13 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
setCurrentItemShowing(MINUTE_INDEX, true, true, false);
announcement += ". " + mSelectMinutes;
} else {
-// mTimePicker.setContentDescription(mHourPickerDescription + ": " + newValue);
+ mTimePicker.setContentDescription(mHourPickerDescription + ": " + newValue);
}
-// Utils.tryAccessibilityAnnounce(mTimePicker, announcement);
+ Utils.tryAccessibilityAnnounce(mTimePicker, announcement);
} else if (pickerIndex == MINUTE_INDEX){
setMinute(newValue);
-// mTimePicker.setContentDescription(mMinutePickerDescription + ": " + newValue);
+ mTimePicker.setContentDescription(mMinutePickerDescription + ": " + newValue);
} else if (pickerIndex == AMPM_INDEX) {
updateAmPmDisplay(newValue);
} else if (pickerIndex == ENABLE_PICKER_INDEX) {
@@ -713,9 +542,6 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
}
private void setHour(int value, boolean announce) {
- // TOneverDO: Set after if-else block (modulo operation changes value!)
- mSelectedHourOfDay = value;
-
String format;
if (mIs24HourMode) {
format = "%02d";
@@ -731,7 +557,7 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
mHourView.setText(text);
mHourSpaceView.setText(text);
if (announce) {
-// Utils.tryAccessibilityAnnounce(mTimePicker, text);
+ Utils.tryAccessibilityAnnounce(mTimePicker, text);
}
}
@@ -740,37 +566,33 @@ public class NumberGridTimePickerDialog extends BaseTimePickerDialog /*DialogFra
value = 0;
}
CharSequence text = String.format(Locale.getDefault(), "%02d", value);
-// Utils.tryAccessibilityAnnounce(mTimePicker, text);
+ Utils.tryAccessibilityAnnounce(mTimePicker, text);
mMinuteView.setText(text);
mMinuteSpaceView.setText(text);
-
- // Setting this here is fine.
- mSelectedMinute = value;
}
// Show either Hours or Minutes.
private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate,
boolean announce) {
-// mTimePicker.setCurrentItemShowing(index, animateCircle);
- setCurrentItemShowing(index);
+ mTimePicker.setCurrentItemShowing(index, animateCircle);
TextView labelToAnimate;
if (index == HOUR_INDEX) {
-// int hours = mTimePicker.getHours();
-// if (!mIs24HourMode) {
-// hours = hours % 12;
-// }
-// mTimePicker.setContentDescription(mHourPickerDescription + ": " + hours);
-// if (announce) {
-// Utils.tryAccessibilityAnnounce(mTimePicker, mSelectHours);
-// }
+ int hours = mTimePicker.getHours();
+ if (!mIs24HourMode) {
+ hours = hours % 12;
+ }
+ mTimePicker.setContentDescription(mHourPickerDescription + ": " + hours);
+ if (announce) {
+ Utils.tryAccessibilityAnnounce(mTimePicker, mSelectHours);
+ }
labelToAnimate = mHourView;
} else {
-// int minutes = mTimePicker.getMinutes();
-// mTimePicker.setContentDescription(mMinutePickerDescription + ": " + minutes);
-// if (announce) {
-// Utils.tryAccessibilityAnnounce(mTimePicker, mSelectMinutes);
-// }
+ int minutes = mTimePicker.getMinutes();
+ mTimePicker.setContentDescription(mMinutePickerDescription + ": " + minutes);
+ if (announce) {
+ Utils.tryAccessibilityAnnounce(mTimePicker, mSelectMinutes);
+ }
labelToAnimate = mMinuteView;
}
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGrid.java b/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGrid.java
new file mode 100644
index 0000000..05faeaa
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGrid.java
@@ -0,0 +1,143 @@
+package com.philliphsu.clock2.editalarm;
+
+import android.content.Context;
+import android.support.annotation.LayoutRes;
+import android.support.v7.widget.GridLayout;
+import android.util.Log;
+import android.view.View;
+import android.widget.TextView;
+
+import com.philliphsu.clock2.aospdatetimepicker.Utils;
+
+/**
+ * Created by Phillip Hsu on 8/17/2016.
+ */
+public abstract class NumbersGrid extends GridLayout implements View.OnClickListener {
+ private static final String TAG = "NumbersGrid";
+ private static final int COLUMN_COUNT = 3;
+
+ // Package visible so our concrete subclasses (in the same package) can access this.
+ OnNumberSelectedListener mSelectionListener;
+ View mLastSelectedView;
+
+ private final int mDefaultTextColor;
+ private final int mSelectedTextColor;
+
+ private boolean mIsInitialized;
+ private int mSelection; // The number selected from this grid
+
+ public interface OnNumberSelectedListener {
+ void onNumberSelected(int number);
+ }
+
+ @LayoutRes
+ protected abstract int contentLayout();
+
+ public NumbersGrid(Context context) {
+ super(context);
+ setColumnCount(COLUMN_COUNT);
+ inflate(context, contentLayout(), this);
+ // We don't do method binding because we don't know the IDs of
+ // our subclasses' buttons, if any.
+ registerClickListeners();
+ mIsInitialized = false;
+ mDefaultTextColor = Utils.getTextColorPrimary(context);
+ mSelectedTextColor = Utils.getThemeAccentColor(context);
+ // Show the first button as default selected
+ setIndicator(getChildAt(indexOfDefaultValue()));
+ }
+
+ public void initialize(OnNumberSelectedListener listener) {
+ if (mIsInitialized) {
+ Log.e(TAG, "This NumbersGrid may only be initialized once.");
+ return;
+ }
+ mSelectionListener = listener;
+ mIsInitialized = true;
+ }
+
+ public int getSelection() {
+ return mSelection;
+ }
+
+ public void setSelection(int value) {
+ mSelection = value;
+ }
+
+ /**
+ * The default implementation assumes the clicked view is of type TextView,
+ * casts the view accordingly, and parses the number from the text it contains.
+ * @param v the View that was clicked
+ */
+ @Override
+ public void onClick(View v) {
+ TextView tv = (TextView) v;
+ clearIndicator(); // Does nothing if there was no indicator last selected
+ setIndicator(v);
+ mSelection = Integer.parseInt(tv.getText().toString());
+ mSelectionListener.onNumberSelected(mSelection);
+ }
+
+ /**
+ * Returns whether the specified View from our hierarchy can have an
+ * OnClickListener registered on it. The default implementation
+ * checks if this view is of type TextView. Subclasses can override
+ * this to fit their own criteria of what types of Views in their
+ * hierarchy can have a click listener registered on.
+ *
+ * @param view a child view from our hierarchy
+ */
+ protected boolean canRegisterClickListener(View view) {
+ return view instanceof TextView;
+ }
+
+ /**
+ * Sets a selection indicator on the clicked number button. The indicator
+ * is the accent color applied to the button's text.
+ *
+ * @param view the clicked number button
+ */
+ protected void setIndicator(View view) {
+ TextView tv = (TextView) view;
+ tv.setTextColor(mSelectedTextColor);
+ mLastSelectedView = view;
+ }
+
+ /**
+ * Clear the selection indicator on the last selected view. Clearing the indicator
+ * reverts the text color back to its default.
+ */
+ protected void clearIndicator() {
+ if (mLastSelectedView != null) {
+ TextView tv = (TextView) mLastSelectedView;
+ tv.setTextColor(mDefaultTextColor);
+ mLastSelectedView = null;
+ }
+ }
+
+ /**
+ * @return the index for the number button that should have the indicator set on by default.
+ * The base implementation returns 0, for the first child.
+ */
+ protected int indexOfDefaultValue() {
+ return 0;
+ }
+
+ void setTheme(Context context, boolean themeDark) {
+ // TODO: Change background color and text color
+ }
+
+ /**
+ * Iterates through our hierarchy and sets the subclass's implementation of OnClickListener
+ * on each number button encountered. By default, the number buttons are assumed to be of
+ * type TextView.
+ */
+ private void registerClickListeners() {
+ int i = 0;
+ View v;
+ while (i < getChildCount() && canRegisterClickListener(v = getChildAt(i))) {
+ v.setOnClickListener(this);
+ i++;
+ }
+ }
+}
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGridView.java b/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGridView.java
index b462444..2331364 100644
--- a/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGridView.java
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/NumbersGridView.java
@@ -111,7 +111,7 @@ public class NumbersGridView extends GridLayout {
@Override
public void onClick(View v) {
setNumbers(new int[] {0,5,10,15,20,25,30,35,40,45,50,55}, true);
- inflate(getContext(), R.layout.content_number_grid_minute_tuners, NumbersGridView.this);
+ inflate(getContext(), R.layout.content_minutes_grid, NumbersGridView.this);
}
});
i++;
@@ -145,7 +145,7 @@ public class NumbersGridView extends GridLayout {
boolean is24HourMode = DateFormat.is24HourFormat(getContext());
int layout = is24HourMode
? R.layout.content_24h_number_grid
- : R.layout.content_number_grid;
+ : R.layout.content_hours_grid;
inflate(getContext(), layout, this);
if (!is24HourMode) {
setNumbers(new int[] {1,2,3,4,5,6,7,8,9,10,11,12});
diff --git a/app/src/main/java/com/philliphsu/clock2/editalarm/TwentyFourHoursGrid.java b/app/src/main/java/com/philliphsu/clock2/editalarm/TwentyFourHoursGrid.java
new file mode 100644
index 0000000..768df13
--- /dev/null
+++ b/app/src/main/java/com/philliphsu/clock2/editalarm/TwentyFourHoursGrid.java
@@ -0,0 +1,69 @@
+package com.philliphsu.clock2.editalarm;
+
+import android.content.Context;
+import android.view.View;
+
+import com.philliphsu.clock2.R;
+
+/**
+ * Created by Phillip Hsu on 8/17/2016.
+ */
+public class TwentyFourHoursGrid extends NumbersGrid implements View.OnLongClickListener {
+ private static final String TAG = "TwentyFourHoursGrid";
+
+ public TwentyFourHoursGrid(Context context) {
+ super(context);
+ for (int i = 0; i < getChildCount(); i++) {
+ getChildAt(i).setOnLongClickListener(this);
+ }
+ }
+
+ @Override
+ protected int contentLayout() {
+ return R.layout.content_24h_number_grid;
+ }
+
+ @Override
+ protected boolean canRegisterClickListener(View view) {
+ return view instanceof TwentyFourHourGridItem;
+ }
+
+ @Override
+ public void onClick(View v) {
+ // We already verified that this view can have a click listener registered on.
+ // See canRegisterClickListener().
+ TwentyFourHourGridItem item = (TwentyFourHourGridItem) v;
+ clearIndicator();
+ setIndicator(v);
+ int newVal = Integer.parseInt(item.getPrimaryText().toString());
+ setSelection(newVal);
+ mSelectionListener.onNumberSelected(newVal);
+ }
+
+ @Override
+ public boolean onLongClick(View v) {
+ TwentyFourHourGridItem item = (TwentyFourHourGridItem) v;
+ int newVal = Integer.parseInt(item.getSecondaryText().toString());
+ setSelection(newVal);
+ mSelectionListener.onNumberSelected(newVal);
+ clearIndicator();
+ swapTexts();
+ // TOneverDO: Call before swapping texts, because setIndicator() uses the primary TextView.
+ setIndicator(v);
+ return true; // Consume the long click
+ }
+
+ @Override
+ protected void setIndicator(View view) {
+ TwentyFourHourGridItem item = (TwentyFourHourGridItem) view;
+ // Set indicator on the primary TextView
+ super.setIndicator(item.getChildAt(0));
+ }
+
+ public void swapTexts() {
+ for (int i = 0; i < getChildCount(); i++) {
+ View v = getChildAt(i);
+ ((TwentyFourHourGridItem) v).swapTexts();
+ }
+ }
+}
diff --git a/app/src/main/res/layout-v21/content_24h_grid_item.xml b/app/src/main/res/layout-v21/content_24h_grid_item.xml
new file mode 100644
index 0000000..4f5e728
--- /dev/null
+++ b/app/src/main/res/layout-v21/content_24h_grid_item.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_24h_grid_item.xml b/app/src/main/res/layout/content_24h_grid_item.xml
index 8a4c54e..ca7df05 100644
--- a/app/src/main/res/layout/content_24h_grid_item.xml
+++ b/app/src/main/res/layout/content_24h_grid_item.xml
@@ -7,12 +7,15 @@
android:id="@+id/primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="@color/colorPrimary"
- android:textSize="@dimen/grid_element_text_size"/>
+ android:fontFamily="sans-serif-light"
+ android:textSize="@dimen/number_grid_24_hour_item_primary_text_size"
+ android:includeFontPadding="false"
+ style="@style/TextAppearance.AppCompat"/>
+ android:layout_height="wrap_content"
+ android:includeFontPadding="false"/>
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_24h_number_grid.xml b/app/src/main/res/layout/content_24h_number_grid.xml
index cf19b77..3800f4f 100644
--- a/app/src/main/res/layout/content_24h_number_grid.xml
+++ b/app/src/main/res/layout/content_24h_number_grid.xml
@@ -1,15 +1,53 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_hours_grid.xml b/app/src/main/res/layout/content_hours_grid.xml
new file mode 100644
index 0000000..4cb250e
--- /dev/null
+++ b/app/src/main/res/layout/content_hours_grid.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_minutes_grid.xml b/app/src/main/res/layout/content_minutes_grid.xml
new file mode 100644
index 0000000..82c678f
--- /dev/null
+++ b/app/src/main/res/layout/content_minutes_grid.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_number_grid.xml b/app/src/main/res/layout/content_number_grid.xml
deleted file mode 100644
index 56d39df..0000000
--- a/app/src/main/res/layout/content_number_grid.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/content_number_grid_minute_tuners.xml b/app/src/main/res/layout/content_number_grid_minute_tuners.xml
deleted file mode 100644
index 8b5eb44..0000000
--- a/app/src/main/res/layout/content_number_grid_minute_tuners.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_time_picker_number_grid.xml b/app/src/main/res/layout/dialog_time_picker_number_grid.xml
index 737e660..cf15a8a 100644
--- a/app/src/main/res/layout/dialog_time_picker_number_grid.xml
+++ b/app/src/main/res/layout/dialog_time_picker_number_grid.xml
@@ -23,24 +23,24 @@
android:layout_gravity="center" />
-
+ android:layout_below="@id/time_picker"/>
@@ -56,8 +56,7 @@
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
- style="@style/TextAppearance.AppCompat.Button"
- android:textSize="@dimen/half_day_text_size"/>
+ style="@style/TextAppearance.AppCompat.Button"/>
@@ -73,8 +72,7 @@
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
- style="@style/TextAppearance.AppCompat.Button"
- android:textSize="@dimen/half_day_text_size"/>
+ style="@style/TextAppearance.AppCompat.Button"/>
@@ -82,6 +80,8 @@
+
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_number_grid.xml b/app/src/main/res/layout/item_number_grid.xml
deleted file mode 100644
index 91d8a56..0000000
--- a/app/src/main/res/layout/item_number_grid.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values-v21/dimens.xml b/app/src/main/res/values-v21/dimens.xml
index ee89ac1..b505a7b 100644
--- a/app/src/main/res/values-v21/dimens.xml
+++ b/app/src/main/res/values-v21/dimens.xml
@@ -1,7 +1,8 @@
-
+
328dp
56dp
16dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/aosp_datetimepicker_colors.xml b/app/src/main/res/values/aosp_datetimepicker_colors.xml
index 1cc249e..f1147c4 100644
--- a/app/src/main/res/values/aosp_datetimepicker_colors.xml
+++ b/app/src/main/res/values/aosp_datetimepicker_colors.xml
@@ -38,15 +38,13 @@
#ff3333
#853333
- #404040
- #363636
+ #424242
+ #212121
#808080
#ffffff
#888888
#bfbfbf
-
- #009688
- #76ffffff
- #00796b
+
+ #a2ffffff
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 227fd33..ab9a21d 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -2,7 +2,7 @@
#3F51B5
#303F9F
- #FF4081
+ #FF4081
#66000000
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 5b0c81e..430df77 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -20,10 +20,18 @@
300dp
64dp
80dp
- 344dp
+ 344dp
88dp
0dp
+
+ 308dp
+ 70dp
+ 56dp
+ 48dp
+ 30sp
+ 28sp
+
24dp
16dp
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 6f9c550..9838fff 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -47,6 +47,24 @@
- sans-serif-light
+
+
+
+