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