mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Implement reminder time picker; customize picker color
This commit is contained in:
@@ -41,8 +41,8 @@ public class AmPmCirclesView extends View {
|
||||
private final Paint mPaint = new Paint();
|
||||
private int mSelectedAlpha;
|
||||
private int mUnselectedColor;
|
||||
private int mAmPmTextColor;
|
||||
private int mSelectedColor;
|
||||
protected int mAmPmTextColor = Color.WHITE;
|
||||
protected int mSelectedColor = Color.BLUE;
|
||||
private float mCircleRadiusMultiplier;
|
||||
private float mAmPmCircleRadiusMultiplier;
|
||||
private String mAmText;
|
||||
@@ -73,8 +73,8 @@ public class AmPmCirclesView extends View {
|
||||
|
||||
Resources res = context.getResources();
|
||||
mUnselectedColor = res.getColor(R.color.white);
|
||||
mSelectedColor = res.getColor(R.color.blue);
|
||||
mAmPmTextColor = res.getColor(R.color.ampm_text_color);
|
||||
//mSelectedColor = res.getColor(R.color.blue);
|
||||
//mAmPmTextColor = res.getColor(R.color.ampm_text_color);
|
||||
mSelectedAlpha = SELECTED_ALPHA;
|
||||
String typefaceFamily = res.getString(R.string.sans_serif);
|
||||
Typeface tf = Typeface.create(typefaceFamily, Typeface.NORMAL);
|
||||
@@ -105,8 +105,8 @@ public class AmPmCirclesView extends View {
|
||||
mSelectedAlpha = SELECTED_ALPHA_THEME_DARK;
|
||||
} else {
|
||||
mUnselectedColor = res.getColor(R.color.white);
|
||||
mSelectedColor = res.getColor(R.color.blue);
|
||||
mAmPmTextColor = res.getColor(R.color.ampm_text_color);
|
||||
//mSelectedColor = res.getColor(R.color.blue);
|
||||
//mAmPmTextColor = res.getColor(R.color.ampm_text_color);
|
||||
mSelectedAlpha = SELECTED_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,6 +84,14 @@ public class RadialPickerLayout extends FrameLayout implements OnTouchListener {
|
||||
private AnimatorSet mTransition;
|
||||
private Handler mHandler = new Handler();
|
||||
|
||||
public void setColor(int selectedColor)
|
||||
{
|
||||
mHourRadialSelectorView.mPaint.setColor(selectedColor);
|
||||
mMinuteRadialSelectorView.mPaint.setColor(selectedColor);
|
||||
mAmPmCirclesView.mSelectedColor = selectedColor;
|
||||
mAmPmCirclesView.mAmPmTextColor = selectedColor;
|
||||
}
|
||||
|
||||
public interface OnValueSelectedListener {
|
||||
void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class RadialSelectorView extends View {
|
||||
// Alpha level for the line.
|
||||
private static final int FULL_ALPHA = Utils.FULL_ALPHA;
|
||||
|
||||
private final Paint mPaint = new Paint();
|
||||
protected final Paint mPaint = new Paint();
|
||||
|
||||
private boolean mIsInitialized;
|
||||
private boolean mDrawValuesReady;
|
||||
@@ -96,8 +96,6 @@ public class RadialSelectorView extends View {
|
||||
|
||||
Resources res = context.getResources();
|
||||
|
||||
int blue = res.getColor(R.color.blue);
|
||||
mPaint.setColor(blue);
|
||||
mPaint.setAntiAlias(true);
|
||||
mSelectionAlpha = SELECTED_ALPHA;
|
||||
|
||||
@@ -139,15 +137,11 @@ public class RadialSelectorView extends View {
|
||||
|
||||
/* package */ void setTheme(Context context, boolean themeDark) {
|
||||
Resources res = context.getResources();
|
||||
int color;
|
||||
if (themeDark) {
|
||||
color = res.getColor(R.color.red);
|
||||
mSelectionAlpha = SELECTED_ALPHA_THEME_DARK;
|
||||
} else {
|
||||
color = res.getColor(R.color.blue);
|
||||
mSelectionAlpha = SELECTED_ALPHA;
|
||||
}
|
||||
mPaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,9 @@ import android.app.*;
|
||||
import android.content.*;
|
||||
import android.content.res.*;
|
||||
import android.os.*;
|
||||
|
||||
import androidx.appcompat.app.*;
|
||||
|
||||
import android.util.*;
|
||||
import android.view.*;
|
||||
import android.view.View.*;
|
||||
@@ -39,7 +41,8 @@ import java.util.*;
|
||||
/**
|
||||
* Dialog to set a time.
|
||||
*/
|
||||
public class TimePickerDialog extends AppCompatDialogFragment implements OnValueSelectedListener{
|
||||
public class TimePickerDialog extends AppCompatDialogFragment implements OnValueSelectedListener
|
||||
{
|
||||
private static final String TAG = "TimePickerDialog";
|
||||
|
||||
private static final String KEY_HOUR_OF_DAY = "hour_of_day";
|
||||
@@ -108,37 +111,50 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
* The callback interface used to indicate the user is done filling in
|
||||
* the time (they clicked on the 'Set' button).
|
||||
*/
|
||||
public interface OnTimeSetListener {
|
||||
public interface OnTimeSetListener
|
||||
{
|
||||
|
||||
/**
|
||||
* @param view The view associated with this listener.
|
||||
* @param view The view associated with this listener.
|
||||
* @param hourOfDay The hour that was set.
|
||||
* @param minute The minute that was set.
|
||||
* @param minute The minute that was set.
|
||||
*/
|
||||
void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute);
|
||||
|
||||
default void onTimeCleared(RadialPickerLayout view) {}
|
||||
default void onTimeCleared(RadialPickerLayout view)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public TimePickerDialog() {
|
||||
public TimePickerDialog()
|
||||
{
|
||||
// Empty constructor required for dialog fragment.
|
||||
}
|
||||
|
||||
@SuppressLint("Java")
|
||||
public TimePickerDialog(Context context, int theme, OnTimeSetListener callback,
|
||||
int hourOfDay, int minute, boolean is24HourMode) {
|
||||
int hourOfDay, int minute, boolean is24HourMode)
|
||||
{
|
||||
// Empty constructor required for dialog fragment.
|
||||
}
|
||||
|
||||
public static TimePickerDialog newInstance(OnTimeSetListener callback,
|
||||
int hourOfDay, int minute, boolean is24HourMode) {
|
||||
int hourOfDay,
|
||||
int minute,
|
||||
boolean is24HourMode,
|
||||
int color)
|
||||
{
|
||||
TimePickerDialog ret = new TimePickerDialog();
|
||||
ret.initialize(callback, hourOfDay, minute, is24HourMode);
|
||||
ret.initialize(callback, hourOfDay, minute, is24HourMode, color);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void initialize(OnTimeSetListener callback,
|
||||
int hourOfDay, int minute, boolean is24HourMode) {
|
||||
int hourOfDay,
|
||||
int minute,
|
||||
boolean is24HourMode,
|
||||
int color)
|
||||
{
|
||||
mCallback = callback;
|
||||
|
||||
mInitialHourOfDay = hourOfDay;
|
||||
@@ -146,35 +162,41 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
mIs24HourMode = is24HourMode;
|
||||
mInKbMode = false;
|
||||
mThemeDark = false;
|
||||
mSelectedColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a dark or light theme. NOTE: this will only take effect for the next onCreateView.
|
||||
*/
|
||||
public void setThemeDark(boolean dark) {
|
||||
public void setThemeDark(boolean dark)
|
||||
{
|
||||
mThemeDark = dark;
|
||||
}
|
||||
|
||||
public boolean isThemeDark() {
|
||||
public boolean isThemeDark()
|
||||
{
|
||||
return mThemeDark;
|
||||
}
|
||||
|
||||
public void setOnTimeSetListener(OnTimeSetListener callback) {
|
||||
public void setOnTimeSetListener(OnTimeSetListener callback)
|
||||
{
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
public void setStartTime(int hourOfDay, int minute) {
|
||||
public void setStartTime(int hourOfDay, int minute)
|
||||
{
|
||||
mInitialHourOfDay = hourOfDay;
|
||||
mInitialMinute = minute;
|
||||
mInKbMode = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
if (savedInstanceState != null && savedInstanceState.containsKey(KEY_HOUR_OF_DAY)
|
||||
&& savedInstanceState.containsKey(KEY_MINUTE)
|
||||
&& savedInstanceState.containsKey(KEY_IS_24_HOUR_VIEW)) {
|
||||
&& 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);
|
||||
@@ -191,7 +213,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Bundle savedInstanceState)
|
||||
{
|
||||
getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
|
||||
View view = inflater.inflate(R.layout.time_picker_dialog, null);
|
||||
@@ -203,8 +226,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
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? R.color.white : R.color.numbers_text_color);
|
||||
//mSelectedColor = res.getColor(mThemeDark ? R.color.red : R.color.blue);
|
||||
mUnselectedColor = res.getColor(mThemeDark ? R.color.white : R.color.numbers_text_color);
|
||||
|
||||
mHourView = (TextView) view.findViewById(R.id.hours);
|
||||
mHourView.setOnKeyListener(keyboardListener);
|
||||
@@ -223,8 +246,9 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
mTimePicker = (RadialPickerLayout) view.findViewById(R.id.time_picker);
|
||||
mTimePicker.setOnValueSelectedListener(this);
|
||||
mTimePicker.setOnKeyListener(keyboardListener);
|
||||
mTimePicker.setColor(mSelectedColor);
|
||||
mTimePicker.initialize(getActivity(), mHapticFeedbackController, mInitialHourOfDay,
|
||||
mInitialMinute, mIs24HourMode);
|
||||
mInitialMinute, mIs24HourMode);
|
||||
|
||||
int currentItemShowing = HOUR_INDEX;
|
||||
if (savedInstanceState != null &&
|
||||
@@ -234,25 +258,31 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
setCurrentItemShowing(currentItemShowing, false, true, true);
|
||||
mTimePicker.invalidate();
|
||||
|
||||
mHourView.setOnClickListener(new OnClickListener() {
|
||||
mHourView.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
public void onClick(View v)
|
||||
{
|
||||
setCurrentItemShowing(HOUR_INDEX, true, false, true);
|
||||
tryVibrate();
|
||||
}
|
||||
});
|
||||
mMinuteView.setOnClickListener(new OnClickListener() {
|
||||
mMinuteView.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
public void onClick(View v)
|
||||
{
|
||||
setCurrentItemShowing(MINUTE_INDEX, true, false, true);
|
||||
tryVibrate();
|
||||
}
|
||||
});
|
||||
|
||||
mDoneButton = (TextView) view.findViewById(R.id.done_button);
|
||||
mDoneButton.setOnClickListener(new OnClickListener() {
|
||||
mDoneButton.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mInKbMode && isTypedTimeFullyLegal()) {
|
||||
finishKbMode(false);
|
||||
} else {
|
||||
@@ -260,7 +290,7 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.onTimeSet(mTimePicker,
|
||||
mTimePicker.getHours(), mTimePicker.getMinutes());
|
||||
mTimePicker.getHours(), mTimePicker.getMinutes());
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
@@ -269,16 +299,16 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
mClearButton = (TextView) view.findViewById(R.id.clear_button);
|
||||
mClearButton.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(mCallback != null) {
|
||||
mCallback.onTimeCleared(mTimePicker);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if (mCallback != null) {
|
||||
mCallback.onTimeCleared(mTimePicker);
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
});
|
||||
mClearButton.setOnKeyListener(keyboardListener);
|
||||
|
||||
// Enable or disable the AM/PM view.
|
||||
@@ -293,15 +323,17 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
separatorView.setLayoutParams(paramsSeparator);
|
||||
} else {
|
||||
mAmPmTextView.setVisibility(View.VISIBLE);
|
||||
updateAmPmDisplay(mInitialHourOfDay < 12? AM : PM);
|
||||
mAmPmHitspace.setOnClickListener(new OnClickListener() {
|
||||
updateAmPmDisplay(mInitialHourOfDay < 12 ? AM : PM);
|
||||
mAmPmHitspace.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
public void onClick(View v)
|
||||
{
|
||||
tryVibrate();
|
||||
int amOrPm = mTimePicker.getIsCurrentlyAmOrPm();
|
||||
if (amOrPm == AM) {
|
||||
amOrPm = PM;
|
||||
} else if (amOrPm == PM){
|
||||
} else if (amOrPm == PM) {
|
||||
amOrPm = AM;
|
||||
}
|
||||
updateAmPmDisplay(amOrPm);
|
||||
@@ -328,56 +360,61 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
mTypedTimes = new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
// Set the theme at the end so that the initialize()s above don't counteract the theme.
|
||||
mTimePicker.setTheme(getActivity().getApplicationContext(), mThemeDark);
|
||||
// Prepare some palette to use.
|
||||
int white = res.getColor(R.color.white);
|
||||
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);
|
||||
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);
|
||||
ColorStateList darkDoneTextColor = res.getColorStateList(R.color.done_text_color_dark);
|
||||
int darkDoneBackground = R.drawable.done_background_color_dark;
|
||||
// // Set the theme at the end so that the initialize()s above don't counteract the theme.
|
||||
// mTimePicker.setTheme(getActivity().getApplicationContext(), mThemeDark);
|
||||
// // Prepare some palette to use.
|
||||
// int white = res.getColor(R.color.white);
|
||||
// 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);
|
||||
// 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);
|
||||
// ColorStateList darkDoneTextColor = res.getColorStateList(R.color.done_text_color_dark);
|
||||
// int darkDoneBackground = R.drawable.done_background_color_dark;
|
||||
|
||||
// Set the palette 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.line).setBackgroundColor(mThemeDark? darkLine : line);
|
||||
mDoneButton.setTextColor(mThemeDark? darkDoneTextColor : doneTextColor);
|
||||
mTimePicker.setBackgroundColor(mThemeDark? lightGray : circleBackground);
|
||||
mDoneButton.setBackgroundResource(mThemeDark? darkDoneBackground : doneBackground);
|
||||
// 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.line).setBackgroundColor(mThemeDark? darkLine : line);
|
||||
// mDoneButton.setTextColor(mThemeDark? darkDoneTextColor : doneTextColor);
|
||||
// mTimePicker.setBackgroundColor(mThemeDark? lightGray : circleBackground);
|
||||
// mDoneButton.setBackgroundResource(mThemeDark? darkDoneBackground : doneBackground);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
public void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
mHapticFeedbackController.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
public void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
mHapticFeedbackController.stop();
|
||||
}
|
||||
|
||||
public void tryVibrate() {
|
||||
public void tryVibrate()
|
||||
{
|
||||
mHapticFeedbackController.tryVibrate();
|
||||
}
|
||||
|
||||
private void updateAmPmDisplay(int amOrPm) {
|
||||
private void updateAmPmDisplay(int amOrPm)
|
||||
{
|
||||
if (amOrPm == AM) {
|
||||
mAmPmTextView.setText(mAmText);
|
||||
Utils.tryAccessibilityAnnounce(mTimePicker, mAmText);
|
||||
mAmPmHitspace.setContentDescription(mAmText);
|
||||
} else if (amOrPm == PM){
|
||||
} else if (amOrPm == PM) {
|
||||
mAmPmTextView.setText(mPmText);
|
||||
Utils.tryAccessibilityAnnounce(mTimePicker, mPmText);
|
||||
mAmPmHitspace.setContentDescription(mPmText);
|
||||
@@ -387,7 +424,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
if (mTimePicker != null) {
|
||||
outState.putInt(KEY_HOUR_OF_DAY, mTimePicker.getHours());
|
||||
outState.putInt(KEY_MINUTE, mTimePicker.getMinutes());
|
||||
@@ -405,7 +443,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
* Called by the picker for updating the header display.
|
||||
*/
|
||||
@Override
|
||||
public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) {
|
||||
public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance)
|
||||
{
|
||||
if (pickerIndex == HOUR_INDEX) {
|
||||
setHour(newValue, false);
|
||||
String announcement = String.format("%d", newValue);
|
||||
@@ -417,7 +456,7 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
|
||||
Utils.tryAccessibilityAnnounce(mTimePicker, announcement);
|
||||
} else if (pickerIndex == MINUTE_INDEX){
|
||||
} else if (pickerIndex == MINUTE_INDEX) {
|
||||
setMinute(newValue);
|
||||
mTimePicker.setContentDescription(mMinutePickerDescription + ": " + newValue);
|
||||
} else if (pickerIndex == AMPM_INDEX) {
|
||||
@@ -430,7 +469,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private void setHour(int value, boolean announce) {
|
||||
private void setHour(int value, boolean announce)
|
||||
{
|
||||
String format;
|
||||
if (mIs24HourMode) {
|
||||
format = "%02d";
|
||||
@@ -450,7 +490,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private void setMinute(int value) {
|
||||
private void setMinute(int value)
|
||||
{
|
||||
if (value == 60) {
|
||||
value = 0;
|
||||
}
|
||||
@@ -462,7 +503,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
// Show either Hours or Minutes.
|
||||
private void setCurrentItemShowing(int index, boolean animateCircle, boolean delayLabelAnimate,
|
||||
boolean announce) {
|
||||
boolean announce)
|
||||
{
|
||||
mTimePicker.setCurrentItemShowing(index, animateCircle);
|
||||
|
||||
TextView labelToAnimate;
|
||||
@@ -485,8 +527,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
labelToAnimate = mMinuteView;
|
||||
}
|
||||
|
||||
int hourColor = (index == HOUR_INDEX)? mSelectedColor : mUnselectedColor;
|
||||
int minuteColor = (index == MINUTE_INDEX)? mSelectedColor : mUnselectedColor;
|
||||
int hourColor = (index == HOUR_INDEX) ? mSelectedColor : mUnselectedColor;
|
||||
int minuteColor = (index == MINUTE_INDEX) ? mSelectedColor : mUnselectedColor;
|
||||
mHourView.setTextColor(hourColor);
|
||||
mMinuteView.setTextColor(minuteColor);
|
||||
|
||||
@@ -499,15 +541,17 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
/**
|
||||
* For keyboard mode, processes key events.
|
||||
*
|
||||
* @param keyCode the pressed key.
|
||||
* @return true if the key was successfully processed, false otherwise.
|
||||
*/
|
||||
private boolean processKeyUp(int keyCode) {
|
||||
private boolean processKeyUp(int keyCode)
|
||||
{
|
||||
if (keyCode == KeyEvent.KEYCODE_ESCAPE || keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
dismiss();
|
||||
return true;
|
||||
} else if (keyCode == KeyEvent.KEYCODE_TAB) {
|
||||
if(mInKbMode) {
|
||||
if (mInKbMode) {
|
||||
if (isTypedTimeFullyLegal()) {
|
||||
finishKbMode(true);
|
||||
}
|
||||
@@ -522,7 +566,7 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.onTimeSet(mTimePicker,
|
||||
mTimePicker.getHours(), mTimePicker.getMinutes());
|
||||
mTimePicker.getHours(), mTimePicker.getMinutes());
|
||||
}
|
||||
dismiss();
|
||||
return true;
|
||||
@@ -539,7 +583,7 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
deletedKeyStr = String.format("%d", getValFromKeyCode(deleted));
|
||||
}
|
||||
Utils.tryAccessibilityAnnounce(mTimePicker,
|
||||
String.format(mDeletedKeyFormat, deletedKeyStr));
|
||||
String.format(mDeletedKeyFormat, deletedKeyStr));
|
||||
updateDisplay(true);
|
||||
}
|
||||
}
|
||||
@@ -549,7 +593,7 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|| keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7
|
||||
|| keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9
|
||||
|| (!mIs24HourMode &&
|
||||
(keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) {
|
||||
(keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) {
|
||||
if (!mInKbMode) {
|
||||
if (mTimePicker == null) {
|
||||
// Something's wrong, because time picker should definitely not be null.
|
||||
@@ -572,11 +616,13 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
/**
|
||||
* Try to start keyboard mode with the specified key, as long as the timepicker is not in the
|
||||
* middle of a touch-event.
|
||||
*
|
||||
* @param keyCode The key to use as the first press. Keyboard mode will not be started if the
|
||||
* key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting
|
||||
* key.
|
||||
* key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting
|
||||
* key.
|
||||
*/
|
||||
private void tryStartingKbMode(int keyCode) {
|
||||
private void tryStartingKbMode(int keyCode)
|
||||
{
|
||||
if (mTimePicker.trySettingInputEnabled(false) &&
|
||||
(keyCode == -1 || addKeyIfLegal(keyCode))) {
|
||||
mInKbMode = true;
|
||||
@@ -585,7 +631,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addKeyIfLegal(int keyCode) {
|
||||
private boolean addKeyIfLegal(int keyCode)
|
||||
{
|
||||
// If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode,
|
||||
// we'll need to see if AM/PM have been typed.
|
||||
if ((mIs24HourMode && mTypedTimes.size() == 4) ||
|
||||
@@ -617,7 +664,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
* Traverse the tree to see if the keys that have been typed so far are legal as is,
|
||||
* or may become legal as more keys are typed (excluding backspace).
|
||||
*/
|
||||
private boolean isTypedTimeLegalSoFar() {
|
||||
private boolean isTypedTimeLegalSoFar()
|
||||
{
|
||||
Node node = mLegalTimesTree;
|
||||
for (int keyCode : mTypedTimes) {
|
||||
node = node.canReach(keyCode);
|
||||
@@ -631,7 +679,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
/**
|
||||
* Check if the time that has been typed so far is completely legal, as is.
|
||||
*/
|
||||
private boolean isTypedTimeFullyLegal() {
|
||||
private boolean isTypedTimeFullyLegal()
|
||||
{
|
||||
if (mIs24HourMode) {
|
||||
// For 24-hour mode, the time is legal if the hours and minutes are each legal. Note:
|
||||
// getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode.
|
||||
@@ -645,7 +694,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private int deleteLastTypedKey() {
|
||||
private int deleteLastTypedKey()
|
||||
{
|
||||
int deleted = mTypedTimes.remove(mTypedTimes.size() - 1);
|
||||
if (!isTypedTimeFullyLegal()) {
|
||||
mDoneButton.setEnabled(false);
|
||||
@@ -655,9 +705,11 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
/**
|
||||
* Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time.
|
||||
*
|
||||
* @param changeDisplays If true, update the displays with the relevant time.
|
||||
*/
|
||||
private void finishKbMode(boolean updateDisplays) {
|
||||
private void finishKbMode(boolean updateDisplays)
|
||||
{
|
||||
mInKbMode = false;
|
||||
if (!mTypedTimes.isEmpty()) {
|
||||
int values[] = getEnteredTime(null);
|
||||
@@ -677,29 +729,31 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
* Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is
|
||||
* empty, either show an empty display (filled with the placeholder text), or update from the
|
||||
* timepicker's values.
|
||||
*
|
||||
* @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text.
|
||||
* Otherwise, revert to the timepicker's values.
|
||||
* Otherwise, revert to the timepicker's values.
|
||||
*/
|
||||
private void updateDisplay(boolean allowEmptyDisplay) {
|
||||
private void updateDisplay(boolean allowEmptyDisplay)
|
||||
{
|
||||
if (!allowEmptyDisplay && mTypedTimes.isEmpty()) {
|
||||
int hour = mTimePicker.getHours();
|
||||
int minute = mTimePicker.getMinutes();
|
||||
setHour(hour, true);
|
||||
setMinute(minute);
|
||||
if (!mIs24HourMode) {
|
||||
updateAmPmDisplay(hour < 12? AM : PM);
|
||||
updateAmPmDisplay(hour < 12 ? AM : PM);
|
||||
}
|
||||
setCurrentItemShowing(mTimePicker.getCurrentItemShowing(), true, true, true);
|
||||
mDoneButton.setEnabled(true);
|
||||
} else {
|
||||
Boolean[] enteredZeros = {false, false};
|
||||
int[] values = getEnteredTime(enteredZeros);
|
||||
String hourFormat = enteredZeros[0]? "%02d" : "%2d";
|
||||
String minuteFormat = (enteredZeros[1])? "%02d" : "%2d";
|
||||
String hourStr = (values[0] == -1)? mDoublePlaceholderText :
|
||||
String.format(hourFormat, values[0]).replace(' ', mPlaceholderText);
|
||||
String minuteStr = (values[1] == -1)? mDoublePlaceholderText :
|
||||
String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText);
|
||||
String hourFormat = enteredZeros[0] ? "%02d" : "%2d";
|
||||
String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d";
|
||||
String hourStr = (values[0] == -1) ? mDoublePlaceholderText :
|
||||
String.format(hourFormat, values[0]).replace(' ', mPlaceholderText);
|
||||
String minuteStr = (values[1] == -1) ? mDoublePlaceholderText :
|
||||
String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText);
|
||||
mHourView.setText(hourStr);
|
||||
mHourSpaceView.setText(hourStr);
|
||||
mHourView.setTextColor(mUnselectedColor);
|
||||
@@ -712,7 +766,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private static int getValFromKeyCode(int keyCode) {
|
||||
private static int getValFromKeyCode(int keyCode)
|
||||
{
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_0:
|
||||
return 0;
|
||||
@@ -741,20 +796,22 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
|
||||
/**
|
||||
* Get the currently-entered time, as integer values of the hours and minutes typed.
|
||||
*
|
||||
* @param enteredZeros A size-2 boolean array, which the caller should initialize, and which
|
||||
* may then be used for the caller to know whether zeros had been explicitly entered as either
|
||||
* hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's.
|
||||
* may then be used for the caller to know whether zeros had been explicitly entered as either
|
||||
* hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's.
|
||||
* @return A size-3 int array. The first value will be the hours, the second value will be the
|
||||
* minutes, and the third will be either TimePickerDialog.AM or TimePickerDialog.PM.
|
||||
*/
|
||||
private int[] getEnteredTime(Boolean[] enteredZeros) {
|
||||
private int[] getEnteredTime(Boolean[] enteredZeros)
|
||||
{
|
||||
int amOrPm = -1;
|
||||
int startIndex = 1;
|
||||
if (!mIs24HourMode && isTypedTimeFullyLegal()) {
|
||||
int keyCode = mTypedTimes.get(mTypedTimes.size() - 1);
|
||||
if (keyCode == getAmOrPmKeyCode(AM)) {
|
||||
amOrPm = AM;
|
||||
} else if (keyCode == getAmOrPmKeyCode(PM)){
|
||||
} else if (keyCode == getAmOrPmKeyCode(PM)) {
|
||||
amOrPm = PM;
|
||||
}
|
||||
startIndex = 2;
|
||||
@@ -765,15 +822,15 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i));
|
||||
if (i == startIndex) {
|
||||
minute = val;
|
||||
} else if (i == startIndex+1) {
|
||||
minute += 10*val;
|
||||
} else if (i == startIndex + 1) {
|
||||
minute += 10 * val;
|
||||
if (enteredZeros != null && val == 0) {
|
||||
enteredZeros[1] = true;
|
||||
}
|
||||
} else if (i == startIndex+2) {
|
||||
} else if (i == startIndex + 2) {
|
||||
hour = val;
|
||||
} else if (i == startIndex+3) {
|
||||
hour += 10*val;
|
||||
} else if (i == startIndex + 3) {
|
||||
hour += 10 * val;
|
||||
if (enteredZeros != null && val == 0) {
|
||||
enteredZeros[0] = true;
|
||||
}
|
||||
@@ -787,7 +844,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
/**
|
||||
* Get the keycode value for AM and PM in the current language.
|
||||
*/
|
||||
private int getAmOrPmKeyCode(int amOrPm) {
|
||||
private int getAmOrPmKeyCode(int amOrPm)
|
||||
{
|
||||
// Cache the codes.
|
||||
if (mAmKeyCode == -1 || mPmKeyCode == -1) {
|
||||
// Find the first character in the AM/PM text that is unique.
|
||||
@@ -822,7 +880,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
/**
|
||||
* Create a tree for deciding what keys can legally be typed.
|
||||
*/
|
||||
private void generateLegalTimesTree() {
|
||||
private void generateLegalTimesTree()
|
||||
{
|
||||
// Create a quick cache of numbers to their keycodes.
|
||||
int k0 = KeyEvent.KEYCODE_0;
|
||||
int k1 = KeyEvent.KEYCODE_1;
|
||||
@@ -955,20 +1014,24 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
* mLegalKeys represents the keys that can be typed to get to the node.
|
||||
* mChildren are the children that can be reached from this node.
|
||||
*/
|
||||
private class Node {
|
||||
private class Node
|
||||
{
|
||||
private int[] mLegalKeys;
|
||||
private ArrayList<Node> mChildren;
|
||||
|
||||
public Node(int... legalKeys) {
|
||||
public Node(int... legalKeys)
|
||||
{
|
||||
mLegalKeys = legalKeys;
|
||||
mChildren = new ArrayList<Node>();
|
||||
}
|
||||
|
||||
public void addChild(Node child) {
|
||||
public void addChild(Node child)
|
||||
{
|
||||
mChildren.add(child);
|
||||
}
|
||||
|
||||
public boolean containsKey(int key) {
|
||||
public boolean containsKey(int key)
|
||||
{
|
||||
for (int i = 0; i < mLegalKeys.length; i++) {
|
||||
if (mLegalKeys[i] == key) {
|
||||
return true;
|
||||
@@ -977,7 +1040,8 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
return false;
|
||||
}
|
||||
|
||||
public Node canReach(int key) {
|
||||
public Node canReach(int key)
|
||||
{
|
||||
if (mChildren == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -990,9 +1054,11 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
private class KeyboardListener implements OnKeyListener {
|
||||
private class KeyboardListener implements OnKeyListener
|
||||
{
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event)
|
||||
{
|
||||
if (event.getAction() == KeyEvent.ACTION_UP) {
|
||||
return processKeyUp(keyCode);
|
||||
}
|
||||
@@ -1000,14 +1066,16 @@ public class TimePickerDialog extends AppCompatDialogFragment implements OnValue
|
||||
}
|
||||
}
|
||||
|
||||
public void setDismissListener( DialogInterface.OnDismissListener listener ) {
|
||||
public void setDismissListener(DialogInterface.OnDismissListener listener)
|
||||
{
|
||||
dismissListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{
|
||||
super.onDismiss(dialog);
|
||||
if( dismissListener != null )
|
||||
if (dismissListener != null)
|
||||
dismissListener.onDismiss(dialog);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,33 +49,33 @@
|
||||
android:layout_height="1dip"
|
||||
android:background="@color/line_background" />
|
||||
|
||||
<LinearLayout
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
style="?android:attr/buttonBarStyle"
|
||||
android:layout_width="@dimen/date_picker_component_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<Button
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:id="@+id/clear_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/done_background_color"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="#333"
|
||||
android:text="@string/clear_label"
|
||||
android:textColor="@color/done_text_color"
|
||||
android:textSize="@dimen/done_label_size" />
|
||||
|
||||
<Button
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
style="?android:attr/buttonBarButtonStyle"
|
||||
android:id="@+id/done_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/done_background_color"
|
||||
android:minHeight="48dp"
|
||||
android:textColor="#333"
|
||||
android:text="@string/done_label"
|
||||
android:textColor="@color/done_text_color"
|
||||
android:textSize="@dimen/done_label_size" />
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -22,8 +22,11 @@ package org.isoron.uhabits.activities.habits.edit
|
||||
import android.content.res.*
|
||||
import android.graphics.*
|
||||
import android.os.*
|
||||
import android.text.format.*
|
||||
import androidx.appcompat.app.*
|
||||
import com.android.datetimepicker.time.*
|
||||
import org.isoron.androidbase.utils.*
|
||||
import org.isoron.uhabits.*
|
||||
import org.isoron.uhabits.activities.*
|
||||
import org.isoron.uhabits.activities.common.dialogs.*
|
||||
import org.isoron.uhabits.core.preferences.*
|
||||
@@ -38,8 +41,12 @@ class EditHabitActivity : AppCompatActivity() {
|
||||
private lateinit var binding: ActivityEditHabitBinding
|
||||
|
||||
var paletteColor = 11
|
||||
var androidColor = 0
|
||||
|
||||
var freqNum = 1
|
||||
var freqDen = 1
|
||||
var reminderHour = -1
|
||||
var reminderMin = -1
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -69,7 +76,7 @@ class EditHabitActivity : AppCompatActivity() {
|
||||
populateFrequency()
|
||||
binding.frequencyPicker.setOnClickListener {
|
||||
val dialog = FrequencyPickerDialog(freqNum, freqDen)
|
||||
dialog.onFrequencyPicked = {num, den ->
|
||||
dialog.onFrequencyPicked = { num, den ->
|
||||
freqNum = num
|
||||
freqDen = den
|
||||
populateFrequency()
|
||||
@@ -77,27 +84,55 @@ class EditHabitActivity : AppCompatActivity() {
|
||||
dialog.show(supportFragmentManager, "frequencyPicker")
|
||||
}
|
||||
|
||||
binding.reminderTimePicker.setOnClickListener {
|
||||
val currentHour = if (reminderHour >= 0) reminderHour else 8
|
||||
val currentMin = if (reminderMin >= 0) reminderMin else 0
|
||||
val is24HourMode = DateFormat.is24HourFormat(this)
|
||||
val dialog = TimePickerDialog.newInstance(object : TimePickerDialog.OnTimeSetListener {
|
||||
override fun onTimeSet(view: RadialPickerLayout?, hourOfDay: Int, minute: Int) {
|
||||
reminderHour = hourOfDay
|
||||
reminderMin = minute
|
||||
populateReminder()
|
||||
}
|
||||
override fun onTimeCleared(view: RadialPickerLayout?) {
|
||||
reminderHour = -1
|
||||
reminderMin = -1
|
||||
populateReminder()
|
||||
}
|
||||
}, currentHour, currentMin, is24HourMode, androidColor)
|
||||
dialog.show(supportFragmentManager, "timePicker")
|
||||
}
|
||||
|
||||
binding.buttonSave.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
private fun populateReminder() {
|
||||
if (reminderHour < 0) {
|
||||
binding.reminderTimePicker.text = getString(R.string.reminder_off)
|
||||
} else {
|
||||
val time = AndroidDateUtils.formatTime(this, reminderHour, reminderMin)
|
||||
binding.reminderTimePicker.text = time
|
||||
}
|
||||
}
|
||||
|
||||
private fun populateFrequency() {
|
||||
val label = when {
|
||||
freqNum == 1 && freqDen == 1 -> "Every day"
|
||||
freqNum == 1 && freqDen == 7 -> "Every week"
|
||||
freqNum == 1 && freqDen > 1 -> "Every $freqDen days"
|
||||
freqDen == 7 -> "$freqNum times per week"
|
||||
freqDen == 31 -> "$freqNum times per month"
|
||||
freqNum == 1 && freqDen == 1 -> getString(R.string.every_day)
|
||||
freqNum == 1 && freqDen == 7 -> getString(R.string.every_week)
|
||||
freqNum == 1 && freqDen > 1 -> getString(R.string.every_x_days, freqDen)
|
||||
freqDen == 7 -> getString(R.string.x_times_per_week, freqNum)
|
||||
freqDen == 31 -> getString(R.string.x_times_per_month, freqNum)
|
||||
else -> "Unknown"
|
||||
}
|
||||
binding.frequencyPicker.text = label
|
||||
}
|
||||
|
||||
private fun updateColors() {
|
||||
val androidColor = PaletteUtils.getColor(this, paletteColor)
|
||||
androidColor = PaletteUtils.getColor(this, paletteColor)
|
||||
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)
|
||||
if(!themeSwitcher.isNightMode) {
|
||||
if (!themeSwitcher.isNightMode) {
|
||||
val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f)
|
||||
window.statusBarColor = darkerAndroidColor
|
||||
binding.toolbar.setBackgroundColor(androidColor)
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.isoron.uhabits.activities.habits.edit;
|
||||
|
||||
import android.app.*;
|
||||
import android.content.*;
|
||||
import android.graphics.*;
|
||||
import android.os.*;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -265,7 +266,7 @@ public class EditHabitDialog extends AppCompatDialogFragment
|
||||
boolean is24HourMode = DateFormat.is24HourFormat(getContext());
|
||||
timePicker =
|
||||
TimePickerDialog.newInstance(reminderPanel, currentHour,
|
||||
currentMin, is24HourMode);
|
||||
currentMin, is24HourMode, Color.BLUE);
|
||||
timePicker.show(getFragmentManager(), "timePicker");
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.isoron.uhabits.notifications;
|
||||
|
||||
|
||||
import android.app.*;
|
||||
import android.graphics.*;
|
||||
import android.os.*;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -66,7 +67,8 @@ public class SnoozeDelayPickerActivity extends FragmentActivity
|
||||
},
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(this));
|
||||
DateFormat.is24HourFormat(this),
|
||||
Color.BLUE);
|
||||
dialog.show(getSupportFragmentManager(), "timePicker");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,142 +1,142 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".activities.habits.edit.EditHabitActivity">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".activities.habits.edit.EditHabitActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:elevation="2dp"
|
||||
android:gravity="end"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:title="@string/create_habit"
|
||||
app:titleTextColor="@color/white">
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:elevation="2dp"
|
||||
android:gravity="end"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:title="@string/create_habit"
|
||||
app:titleTextColor="@color/white">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonSave"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/save"
|
||||
android:textColor="@color/white"
|
||||
app:rippleColor="@color/white"
|
||||
app:strokeColor="@color/white" />
|
||||
android:id="@+id/buttonSave"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/save"
|
||||
android:textColor="@color/white"
|
||||
app:rippleColor="@color/white"
|
||||
app:strokeColor="@color/white" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:orientation="vertical">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
|
||||
<!-- Title and color -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- Habit Title -->
|
||||
<FrameLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:text="@string/name" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/name"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
android:padding="16dp"
|
||||
android:hint="e.g. Exercise" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:hint="e.g. Exercise"
|
||||
android:padding="16dp"
|
||||
android:textSize="@dimen/regularTextSize" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Habit Color -->
|
||||
<FrameLayout
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="0dp"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="match_parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:paddingStart="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:text="Color" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Color"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/colorButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:backgroundTint="#E23673"/>
|
||||
android:id="@+id/colorButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:backgroundTint="#E23673" />
|
||||
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -147,166 +147,166 @@
|
||||
|
||||
<!-- Habit Question -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:paddingTop="4dp">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:paddingTop="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:text="@string/question" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/question"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
android:hint="@string/example_question_boolean"
|
||||
android:padding="16dp"
|
||||
android:text="" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:hint="@string/example_question_boolean"
|
||||
android:padding="16dp"
|
||||
android:text=""
|
||||
android:textSize="@dimen/regularTextSize" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Frequency -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:paddingTop="4dp">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp"
|
||||
android:paddingTop="4dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/frequency"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/frequencyPicker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/frequency" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/frequencyPicker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableEnd="@drawable/ic_arrow_drop_down_dark"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
android:padding="16dp"
|
||||
android:text="@string/every_day"
|
||||
android:textColor="?attr/highContrastTextColor" />
|
||||
android:drawableEnd="@drawable/ic_arrow_drop_down_dark"
|
||||
android:padding="16dp"
|
||||
android:text="@string/every_day"
|
||||
android:textColor="?attr/highContrastTextColor"
|
||||
android:textSize="@dimen/regularTextSize" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<!-- Reminder -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/reminder"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/reminderTimePicker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="@string/reminder" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:drawableEnd="@drawable/ic_arrow_drop_down_dark"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
android:textColor="?attr/highContrastTextColor"
|
||||
android:padding="16dp"
|
||||
android:text="@string/reminder_off" />
|
||||
android:drawableEnd="@drawable/ic_arrow_drop_down_dark"
|
||||
android:padding="16dp"
|
||||
android:text="@string/reminder_off"
|
||||
android:textColor="?attr/highContrastTextColor"
|
||||
android:textSize="@dimen/regularTextSize" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<!-- Notes -->
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_input_group"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Notes" />
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="-17dp"
|
||||
android:layout_marginBottom="-4dp"
|
||||
android:background="?attr/highContrastReverseTextColor"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Notes"
|
||||
android:textSize="@dimen/smallTextSize" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:textSize="@dimen/regularTextSize"
|
||||
android:textColor="?attr/highContrastTextColor"
|
||||
android:padding="16dp"
|
||||
android:hint="(Optional)" />
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
android:hint="(Optional)"
|
||||
android:padding="16dp"
|
||||
android:textColor="?attr/highContrastTextColor"
|
||||
android:textSize="@dimen/regularTextSize" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -252,5 +252,7 @@
|
||||
<string name="measurable_example">e.g. How many miles did you run today? How many pages did you read? How many calories did you eat?</string>
|
||||
<string name="subjective">Subjective</string>
|
||||
<string name="subjective_example">e.g. Are you felling happy today? Definitely, somewhat, not at all? How frequently did you snack? Very often, sometimes, never?</string>
|
||||
<string name="x_times_per_week">%d times per week</string>
|
||||
<string name="x_times_per_month">%d times per month</string>
|
||||
|
||||
</resources>
|
||||
Reference in New Issue
Block a user