New numpad time picker layout

This commit is contained in:
Phillip Hsu 2016-07-15 23:43:55 -07:00
parent 69d8812c4a
commit 231aa9a280
6 changed files with 110 additions and 100 deletions

View File

@ -141,7 +141,7 @@ public abstract class GridLayoutNumpad extends GridLayout implements View.OnClic
}
}
public final boolean clear() {
public boolean clear() {
Arrays.fill(mInput, UNMODIFIED);
mCount = 0;
onDigitsCleared();

View File

@ -2,9 +2,11 @@ package com.philliphsu.clock2.editalarm;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.design.widget.FloatingActionButton;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.ImageButton;
import com.philliphsu.clock2.R;
@ -15,6 +17,7 @@ import java.util.Calendar;
import butterknife.Bind;
import butterknife.OnClick;
import butterknife.OnLongClick;
/**
* 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 })
Button[] mAltButtons;
@Bind(R.id.fab) FloatingActionButton mFab;
@Bind(R.id.backspace) ImageButton mBackspace;
public NumpadTimePicker(Context context) {
super(context);
@ -93,6 +98,7 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
}
@Override
@OnClick(R.id.backspace)
public void delete() {
int len = mFormattedInput.length();
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 */
@Override
public int hourOfDay() {
@ -213,6 +225,10 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
return mFormattedInput.toString();
}
public void setFabClickListener(OnClickListener fabClickListener) {
mFab.setOnClickListener(fabClickListener);
}
private void init() {
if (is24HourFormat()) {
mAltButtons[0].setText(R.string.left_alt_24hr);
@ -332,8 +348,17 @@ public class NumpadTimePicker extends GridLayoutNumpad implements TimePicker {
private void updateNumpadStates() {
updateAltButtonStates();
//updateBackspaceState(); // Backspace is not part of the numpad
updateBackspaceState();
updateNumberKeysStates();
updateFabState();
}
private void updateFabState() {
mFab.setEnabled(checkTimeValid());
}
private void updateBackspaceState() {
mBackspace.setEnabled(count() > 0);
}
private void updateAltButtonStates() {

View File

@ -6,24 +6,20 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import com.philliphsu.clock2.R;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnLongClick;
import butterknife.OnTouch;
/**
* Created by Phillip Hsu on 7/12/2016.
*
*/
public class NumpadTimePickerDialog extends DialogFragment
implements NumpadTimePicker.OnInputChangeListener {
public class NumpadTimePickerDialog extends DialogFragment implements NumpadTimePicker.OnInputChangeListener {
private static final String KEY_HOUR_OF_DAY = "hour_of_day";
private static final String KEY_MINUTE = "minute";
@ -45,10 +41,7 @@ public class NumpadTimePickerDialog extends DialogFragment
*/
private int[] mInputtedDigits;
@Bind(R.id.backspace) ImageButton mBackspace;
@Bind(R.id.input) EditText mInputField;
@Bind(R.id.cancel) Button mCancelButton;
@Bind(R.id.ok) Button mOkButton;
@Bind(R.id.input_time) EditText mInputField;
@Bind(R.id.number_grid) NumpadTimePicker mNumpad;
public NumpadTimePickerDialog() {
@ -101,12 +94,24 @@ public class NumpadTimePickerDialog extends DialogFragment
View view = inflater.inflate(R.layout.dialog_time_picker_numpad, container, false);
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.insertDigits(mInputtedDigits); // TOneverDO: before mNumpad.setOnInputChangeListener(this);
// Show the cursor immediately
mInputField.requestFocus(); // TODO: If changed to TextView, then don't need this.
mInputField.requestFocus();
// TODO: Disabled color
updateInputText(""); // Primarily to disable 'OK'
//updateInputText(""); // Primarily to disable 'OK'
return view;
}
@ -135,41 +140,20 @@ public class NumpadTimePickerDialog extends DialogFragment
updateInputText("");
}
// TODO: If you change the input field to a TextView, then you don't need this.
@OnTouch(R.id.input)
@OnTouch(R.id.input_time)
boolean captureTouchOnEditText() {
// Capture touch events on the EditText field, because we want it to do nothing.
return true;
}
@OnClick(R.id.cancel)
@OnClick(R.id.cancel_icon)
void myCancel() {
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) {
mInputField.setText(inputText);
// Move the cursor
//mInputField.setSelection(mInputField.length()); // TODO: If changed to TextView, don't need this
mOkButton.setEnabled(mNumpad.checkTimeValid());
mInputField.setSelection(mInputField.length());
}
}

View File

@ -17,4 +17,31 @@
grid:layout_rowWeight="1"
grid:layout_columnWeight="1"
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>

View File

@ -1,70 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageButton
android:id="@+id/backspace"
android:layout_width="@dimen/header_height"
android:layout_height="@dimen/header_height"
android:src="@drawable/ic_backspace_24dp"
android:background="?selectableItemBackground"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"/>
<!-- TODO: Consider changing to TextView if you don't
want the cursor after all. A reason you may want to do
so is the cursor is getting cut off, most likely because
of the text size being larger than the view bounds. You can
probably solve this by adding some padding. Another reason is
the cursor looks ugly with it blinking. -->
<EditText
android:id="@+id/input"
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"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:listDivider"
android:layout_below="@id/input"/>
android:layout_height="@dimen/header_height"
android:background="@color/colorPrimary">
<ImageButton
android:id="@+id/cancel_icon"
android:layout_width="@dimen/cancel_icon_size"
android:layout_height="match_parent"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:background="?selectableItemBackground"
android:layout_alignParentStart="true"/>
<!-- We want this to be an EditText because the cursor indicates
where the user's input will go. Otherwise, when the dialog first
opens, the user sees the header view as just an appbar that has
a single navigation icon, with no indication that the dialog
actually displays input. -->
<EditText
android:id="@+id/input_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/cancel_icon"
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
android:id="@+id/number_grid"
android:layout_width="match_parent"
android:layout_height="@dimen/numpad_height"
android:layout_below="@id/divider"/>
android:layout_height="@dimen/numpad_height"/>
<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>
</RelativeLayout>
</LinearLayout>

View File

@ -15,5 +15,6 @@
<!-- NumpadTimePickerDialog -->
<dimen name="header_height">72dp</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>