New numpad time picker layout
This commit is contained in:
parent
69d8812c4a
commit
231aa9a280
@ -141,7 +141,7 @@ public abstract class GridLayoutNumpad extends GridLayout implements View.OnClic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean clear() {
|
public boolean clear() {
|
||||||
Arrays.fill(mInput, UNMODIFIED);
|
Arrays.fill(mInput, UNMODIFIED);
|
||||||
mCount = 0;
|
mCount = 0;
|
||||||
onDigitsCleared();
|
onDigitsCleared();
|
||||||
|
|||||||
@ -2,9 +2,11 @@ package com.philliphsu.clock2.editalarm;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.IntDef;
|
import android.support.annotation.IntDef;
|
||||||
|
import android.support.design.widget.FloatingActionButton;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ import java.util.Calendar;
|
|||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
import butterknife.OnLongClick;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Phillip Hsu on 7/12/2016.
|
* Created by Phillip Hsu on 7/12/2016.
|
||||||
@ -48,6 +51,8 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
|
|||||||
|
|
||||||
@Bind({ R.id.leftAlt, R.id.rightAlt })
|
@Bind({ R.id.leftAlt, R.id.rightAlt })
|
||||||
Button[] mAltButtons;
|
Button[] mAltButtons;
|
||||||
|
@Bind(R.id.fab) FloatingActionButton mFab;
|
||||||
|
@Bind(R.id.backspace) ImageButton mBackspace;
|
||||||
|
|
||||||
public NumpadTimePicker(Context context) {
|
public NumpadTimePicker(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -93,6 +98,7 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@OnClick(R.id.backspace)
|
||||||
public void delete() {
|
public void delete() {
|
||||||
int len = mFormattedInput.length();
|
int len = mFormattedInput.length();
|
||||||
if (!is24HourFormat() && mAmPmState != UNSPECIFIED) {
|
if (!is24HourFormat() && mAmPmState != UNSPECIFIED) {
|
||||||
@ -108,6 +114,12 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnLongClick(R.id.backspace)
|
||||||
|
public boolean clear() {
|
||||||
|
return super.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the hour of day (0-23) regardless of clock system */
|
/** Returns the hour of day (0-23) regardless of clock system */
|
||||||
@Override
|
@Override
|
||||||
public int hourOfDay() {
|
public int hourOfDay() {
|
||||||
@ -213,6 +225,10 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
|
|||||||
return mFormattedInput.toString();
|
return mFormattedInput.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFabClickListener(OnClickListener fabClickListener) {
|
||||||
|
mFab.setOnClickListener(fabClickListener);
|
||||||
|
}
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
if (is24HourFormat()) {
|
if (is24HourFormat()) {
|
||||||
mAltButtons[0].setText(R.string.left_alt_24hr);
|
mAltButtons[0].setText(R.string.left_alt_24hr);
|
||||||
@ -332,8 +348,17 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
|
|||||||
|
|
||||||
private void updateNumpadStates() {
|
private void updateNumpadStates() {
|
||||||
updateAltButtonStates();
|
updateAltButtonStates();
|
||||||
//updateBackspaceState(); // Backspace is not part of the numpad
|
updateBackspaceState();
|
||||||
updateNumberKeysStates();
|
updateNumberKeysStates();
|
||||||
|
updateFabState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFabState() {
|
||||||
|
mFab.setEnabled(checkTimeValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBackspaceState() {
|
||||||
|
mBackspace.setEnabled(count() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAltButtonStates() {
|
private void updateAltButtonStates() {
|
||||||
|
|||||||
@ -6,24 +6,20 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
|
||||||
|
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
|
|
||||||
import butterknife.Bind;
|
import butterknife.Bind;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
import butterknife.OnLongClick;
|
|
||||||
import butterknife.OnTouch;
|
import butterknife.OnTouch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Phillip Hsu on 7/12/2016.
|
* Created by Phillip Hsu on 7/12/2016.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class NumpadTimePickerDialog extends DialogFragment
|
public class NumpadTimePickerDialog extends DialogFragment implements NumpadTimePicker.OnInputChangeListener {
|
||||||
implements NumpadTimePicker.OnInputChangeListener {
|
|
||||||
|
|
||||||
private static final String KEY_HOUR_OF_DAY = "hour_of_day";
|
private static final String KEY_HOUR_OF_DAY = "hour_of_day";
|
||||||
private static final String KEY_MINUTE = "minute";
|
private static final String KEY_MINUTE = "minute";
|
||||||
@ -45,10 +41,7 @@ public class NumpadTimePickerDialog extends DialogFragment
|
|||||||
*/
|
*/
|
||||||
private int[] mInputtedDigits;
|
private int[] mInputtedDigits;
|
||||||
|
|
||||||
@Bind(R.id.backspace) ImageButton mBackspace;
|
@Bind(R.id.input_time) EditText mInputField;
|
||||||
@Bind(R.id.input) EditText mInputField;
|
|
||||||
@Bind(R.id.cancel) Button mCancelButton;
|
|
||||||
@Bind(R.id.ok) Button mOkButton;
|
|
||||||
@Bind(R.id.number_grid) NumpadTimePicker mNumpad;
|
@Bind(R.id.number_grid) NumpadTimePicker mNumpad;
|
||||||
|
|
||||||
public NumpadTimePickerDialog() {
|
public NumpadTimePickerDialog() {
|
||||||
@ -101,12 +94,24 @@ public class NumpadTimePickerDialog extends DialogFragment
|
|||||||
View view = inflater.inflate(R.layout.dialog_time_picker_numpad, container, false);
|
View view = inflater.inflate(R.layout.dialog_time_picker_numpad, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
// Can't do a method bind because the FAB is not part of this dialog's layout
|
||||||
|
// Also can't do the bind in the Numpad's class, because it doesn't have access to
|
||||||
|
// the OnTimeSetListener callback contained here or the dialog's dismiss()
|
||||||
|
mNumpad.setFabClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (!mNumpad.checkTimeValid())
|
||||||
|
return;
|
||||||
|
mCallback.onTimeSet(mNumpad, mNumpad.hourOfDay(), mNumpad.minute());
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
mNumpad.setOnInputChangeListener(this);
|
mNumpad.setOnInputChangeListener(this);
|
||||||
mNumpad.insertDigits(mInputtedDigits); // TOneverDO: before mNumpad.setOnInputChangeListener(this);
|
mNumpad.insertDigits(mInputtedDigits); // TOneverDO: before mNumpad.setOnInputChangeListener(this);
|
||||||
// Show the cursor immediately
|
// Show the cursor immediately
|
||||||
mInputField.requestFocus(); // TODO: If changed to TextView, then don't need this.
|
mInputField.requestFocus();
|
||||||
// TODO: Disabled color
|
// TODO: Disabled color
|
||||||
updateInputText(""); // Primarily to disable 'OK'
|
//updateInputText(""); // Primarily to disable 'OK'
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
@ -135,41 +140,20 @@ public class NumpadTimePickerDialog extends DialogFragment
|
|||||||
updateInputText("");
|
updateInputText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: If you change the input field to a TextView, then you don't need this.
|
@OnTouch(R.id.input_time)
|
||||||
@OnTouch(R.id.input)
|
|
||||||
boolean captureTouchOnEditText() {
|
boolean captureTouchOnEditText() {
|
||||||
// Capture touch events on the EditText field, because we want it to do nothing.
|
// Capture touch events on the EditText field, because we want it to do nothing.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.cancel)
|
@OnClick(R.id.cancel_icon)
|
||||||
void myCancel() {
|
void myCancel() {
|
||||||
dismiss();
|
dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.ok)
|
|
||||||
void ok() {
|
|
||||||
if (!mNumpad.checkTimeValid())
|
|
||||||
return;
|
|
||||||
mCallback.onTimeSet(mNumpad, mNumpad.hourOfDay(), mNumpad.minute());
|
|
||||||
dismiss();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnClick(R.id.backspace)
|
|
||||||
void backspace() {
|
|
||||||
mNumpad.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
@OnLongClick(R.id.backspace)
|
|
||||||
boolean longBackspace() {
|
|
||||||
mNumpad.clear();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateInputText(String inputText) {
|
private void updateInputText(String inputText) {
|
||||||
mInputField.setText(inputText);
|
mInputField.setText(inputText);
|
||||||
// Move the cursor
|
// Move the cursor
|
||||||
//mInputField.setSelection(mInputField.length()); // TODO: If changed to TextView, don't need this
|
mInputField.setSelection(mInputField.length());
|
||||||
mOkButton.setEnabled(mNumpad.checkTimeValid());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,4 +17,31 @@
|
|||||||
grid:layout_rowWeight="1"
|
grid:layout_rowWeight="1"
|
||||||
grid:layout_columnWeight="1"
|
grid:layout_columnWeight="1"
|
||||||
grid:layout_column="2"/>
|
grid:layout_column="2"/>
|
||||||
|
|
||||||
|
<!-- Used to properly position the FAB -->
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
grid:layout_rowWeight="1"
|
||||||
|
grid:layout_columnWeight="1"
|
||||||
|
grid:layout_column="1">
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_done_24dp"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/backspace"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:src="@drawable/ic_backspace_24dp"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
|
grid:layout_rowWeight="1"
|
||||||
|
grid:layout_columnWeight="1"
|
||||||
|
grid:layout_column="2"/>
|
||||||
</merge>
|
</merge>
|
||||||
@ -1,70 +1,43 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/header_height"
|
||||||
|
android:background="@color/colorPrimary">
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/backspace"
|
android:id="@+id/cancel_icon"
|
||||||
android:layout_width="@dimen/header_height"
|
android:layout_width="@dimen/cancel_icon_size"
|
||||||
android:layout_height="@dimen/header_height"
|
android:layout_height="match_parent"
|
||||||
android:src="@drawable/ic_backspace_24dp"
|
android:src="@android:drawable/ic_menu_close_clear_cancel"
|
||||||
android:background="?selectableItemBackground"
|
android:background="?selectableItemBackground"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentStart="true"/>
|
||||||
android:layout_alignParentTop="true"/>
|
|
||||||
|
|
||||||
<!-- TODO: Consider changing to TextView if you don't
|
<!-- We want this to be an EditText because the cursor indicates
|
||||||
want the cursor after all. A reason you may want to do
|
where the user's input will go. Otherwise, when the dialog first
|
||||||
so is the cursor is getting cut off, most likely because
|
opens, the user sees the header view as just an appbar that has
|
||||||
of the text size being larger than the view bounds. You can
|
a single navigation icon, with no indication that the dialog
|
||||||
probably solve this by adding some padding. Another reason is
|
actually displays input. -->
|
||||||
the cursor looks ugly with it blinking. -->
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/input"
|
android:id="@+id/input_time"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="@dimen/header_height"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:textSize="@dimen/time_input_text_size"
|
|
||||||
android:focusable="false"
|
|
||||||
android:focusableInTouchMode="false"/>
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:id="@+id/divider"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:listDivider"
|
android:layout_toEndOf="@id/cancel_icon"
|
||||||
android:layout_below="@id/input"/>
|
android:layout_centerInParent="true"
|
||||||
|
android:textSize="@dimen/time_input_text_size"
|
||||||
|
android:text="12:00 AM"
|
||||||
|
android:background="@null"
|
||||||
|
style="@style/TextAppearance.AppCompat.Inverse"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
<com.philliphsu.clock2.editalarm.NumpadTimePicker
|
<com.philliphsu.clock2.editalarm.NumpadTimePicker
|
||||||
android:id="@+id/number_grid"
|
android:id="@+id/number_grid"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/numpad_height"
|
android:layout_height="@dimen/numpad_height"/>
|
||||||
android:layout_below="@id/divider"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/actions"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_below="@id/number_grid">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/cancel"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="CANCEL"
|
|
||||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/ok"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="OK"
|
|
||||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@ -15,5 +15,6 @@
|
|||||||
<!-- NumpadTimePickerDialog -->
|
<!-- NumpadTimePickerDialog -->
|
||||||
<dimen name="header_height">72dp</dimen>
|
<dimen name="header_height">72dp</dimen>
|
||||||
<dimen name="numpad_height">270dp</dimen>
|
<dimen name="numpad_height">270dp</dimen>
|
||||||
<dimen name="time_input_text_size">40sp</dimen>
|
<dimen name="time_input_text_size">45sp</dimen>
|
||||||
|
<dimen name="cancel_icon_size">56dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user