Create new time picker dialog each time as needed
This commit is contained in:
parent
0f32215145
commit
c3b018f59e
@ -4,6 +4,7 @@ import android.content.Intent;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.support.design.widget.CoordinatorLayout;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
@ -73,6 +74,13 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
private static final RelativeSizeSpan AMPM_SIZE_SPAN = new RelativeSizeSpan(0.5f);
|
||||
private static final String TAG_TIME_PICKER = "time_picker";
|
||||
|
||||
private static final String KEY_INPUT_TIME = "input_time";
|
||||
private static final String KEY_ENABLED = "enabled";
|
||||
private static final String KEY_CHECKED_DAYS = "checked_days";
|
||||
private static final String KEY_LABEL = "label";
|
||||
private static final String KEY_RINGTONE_URI = "ringtone";
|
||||
private static final String KEY_VIBRATE = "vibrate";
|
||||
|
||||
private static final int REQUEST_PICK_RINGTONE = 0;
|
||||
private static final int ID_MENU_ITEM = 0;
|
||||
|
||||
@ -82,6 +90,12 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
private int mSelectedHourOfDay = -1;
|
||||
private int mSelctedMinute = -1;
|
||||
|
||||
// If we keep a reference to the dialog, we keep its previous state as well.
|
||||
// So the next time we call show() on this, the input field will show the
|
||||
// last inputted time. The easiest workaround is to always create a new
|
||||
// instance each time we want to show the dialog.
|
||||
// private NumpadTimePickerDialog mPicker;
|
||||
|
||||
@Bind(R.id.main_content) CoordinatorLayout mMainContent;
|
||||
@Bind(R.id.save) Button mSave;
|
||||
@Bind(R.id.delete) Button mDelete;
|
||||
@ -105,7 +119,20 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setWeekDaysText();
|
||||
|
||||
// Are we recreating this Activity because of a rotation? If so, try finding
|
||||
// the time picker in our backstack.
|
||||
NumpadTimePickerDialog picker = (NumpadTimePickerDialog)
|
||||
getSupportFragmentManager().findFragmentByTag(TAG_TIME_PICKER);
|
||||
if (picker != null) {
|
||||
// Restore the callback
|
||||
picker.setOnTimeSetListener(this);
|
||||
// mPicker = picker;
|
||||
}
|
||||
|
||||
// TODO: Delete this
|
||||
mNumpad.setKeyListener(this);
|
||||
|
||||
mOldAlarmId = getIntent().getLongExtra(EXTRA_ALARM_ID, -1);
|
||||
if (mOldAlarmId != -1) {
|
||||
// getLoaderManager() for support fragments by default returns the
|
||||
@ -116,21 +143,74 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
} else {
|
||||
// Nothing to load, so show default values
|
||||
showDetails();
|
||||
// Show the time picker dialog, if it is not already showing
|
||||
// AND this is the very first time the activity is being created
|
||||
if (picker == null && savedInstanceState == null) {
|
||||
// Wait a bit so the activity and dialog don't show at the same time
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
openTimePicker();
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
setTimeTextHint(); // TODO: private access
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Was the time picker in our backstack? It could have been if it was showing
|
||||
// and the device had rotated.
|
||||
NumpadTimePickerDialog picker = (NumpadTimePickerDialog)
|
||||
getSupportFragmentManager().findFragmentByTag(TAG_TIME_PICKER);
|
||||
if (picker != null) {
|
||||
// Restore the callback
|
||||
picker.setOnTimeSetListener(this);
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
// Write out any state we wish to save for re-initialization.
|
||||
// You can either restore this state in onCreate() or by
|
||||
// overriding onRestoreInstanceState() and restoring it there.
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(KEY_INPUT_TIME, mTimeText.getText().toString());
|
||||
// This is restored automatically post-rotation
|
||||
outState.putBoolean(KEY_ENABLED, mSwitch.isChecked());
|
||||
// These are restored automatically post-rotation
|
||||
outState.putBooleanArray(KEY_CHECKED_DAYS, new boolean[] {
|
||||
mDays[0].isChecked(),
|
||||
mDays[1].isChecked(),
|
||||
mDays[2].isChecked(),
|
||||
mDays[3].isChecked(),
|
||||
mDays[4].isChecked(),
|
||||
mDays[5].isChecked(),
|
||||
mDays[6].isChecked()
|
||||
});
|
||||
// This is restored automatically post-rotation
|
||||
outState.putString(KEY_LABEL, mLabel.getText().toString());
|
||||
outState.putParcelable(KEY_RINGTONE_URI, mSelectedRingtoneUri);
|
||||
// This is restored automatically post-rotation
|
||||
outState.putBoolean(KEY_VIBRATE, mVibrate.isChecked());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
// For now, restore the previous state here instead of in onCreate()
|
||||
// because it's easier than refactoring the code over there.
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
// No null-check on the given Bundle is necessary,
|
||||
// because onSaveInstanceState() works with a non-null
|
||||
// Bundle, even in the default implementation.
|
||||
if (savedInstanceState.containsKey(KEY_INPUT_TIME)
|
||||
//&& savedInstanceState.containsKey(KEY_LABEL)
|
||||
&& savedInstanceState.containsKey(KEY_RINGTONE_URI)) {
|
||||
// Make sure we actually saved something, or else we'd get
|
||||
// a null and we'll end up clearing the hints...
|
||||
mTimeText.setText(savedInstanceState.getString(KEY_INPUT_TIME));
|
||||
// mLabel.setText(savedInstanceState.getString(KEY_LABEL));
|
||||
mSelectedRingtoneUri = savedInstanceState.getParcelable(KEY_RINGTONE_URI);
|
||||
// ...this, however, would throw an NPE because
|
||||
// we'd be accessing a null Ringtone.
|
||||
updateRingtoneButtonText();
|
||||
}
|
||||
// TODO: Manually restore the states of the "auto-restoring" widgets.
|
||||
// In onCreate(), we will call showDetails().
|
||||
// You only witnessed the auto-restoring for a blank Alarm, where
|
||||
// the impl of showDetails() is pretty bare. If we have an actual
|
||||
// Alarm, showDetails() could very well change the values displayed
|
||||
// by those widgets based on that Alarm's values, but not based on
|
||||
// any unsaved changes that may have occurred to the widgets previously.
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -359,8 +439,8 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
|
||||
@OnClick(R.id.input_time)
|
||||
void openTimePicker() {
|
||||
NumpadTimePickerDialog picker = NumpadTimePickerDialog.newInstance(EditAlarmActivity.this);
|
||||
picker.show(getSupportFragmentManager(), TAG_TIME_PICKER);
|
||||
NumpadTimePickerDialog.newInstance(EditAlarmActivity.this)
|
||||
.show(getSupportFragmentManager(), TAG_TIME_PICKER);
|
||||
}
|
||||
|
||||
private void setWeekDaysText() {
|
||||
@ -609,7 +689,6 @@ public class EditAlarmActivity extends BaseActivity implements
|
||||
// TODO default values
|
||||
showTimeTextFocused(true);
|
||||
showRingtone(""); // gets default ringtone
|
||||
// TODO: Show the dialog instead
|
||||
//showNumpad(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import butterknife.Bind;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import butterknife.OnLongClick;
|
||||
import butterknife.OnTouch;
|
||||
|
||||
/**
|
||||
* Created by Phillip Hsu on 7/12/2016.
|
||||
@ -35,7 +36,12 @@ public class NumpadTimePickerDialog extends DialogFragment
|
||||
private int mInitialMinute;
|
||||
private boolean mIs24HourMode;
|
||||
/**
|
||||
* The digits stored in the numpad from the last time onSaveInstanceState() was called
|
||||
* The digits stored in the numpad from the last time onSaveInstanceState() was called.
|
||||
*
|
||||
* Why not have the NumpadTimePicker class save state itself? Because it's a lot more
|
||||
* code to do so, as you have to create your own SavedState subclass. Also, we modeled
|
||||
* this dialog class on the RadialTimePickerDialog, where the RadialPickerLayout also
|
||||
* depends on the dialog to save its state.
|
||||
*/
|
||||
private int[] mInputtedDigits;
|
||||
|
||||
@ -97,6 +103,8 @@ public class NumpadTimePickerDialog extends DialogFragment
|
||||
|
||||
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.
|
||||
// TODO: Disabled color
|
||||
updateInputText(""); // Primarily to disable 'OK'
|
||||
|
||||
@ -127,6 +135,13 @@ 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)
|
||||
boolean captureTouchOnEditText() {
|
||||
// Capture touch events on the EditText field, because we want it to do nothing.
|
||||
return true;
|
||||
}
|
||||
|
||||
@OnClick(R.id.cancel)
|
||||
void myCancel() {
|
||||
dismiss();
|
||||
@ -153,6 +168,8 @@ public class NumpadTimePickerDialog extends DialogFragment
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,24 +5,29 @@
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/backspace"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
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="72dp"
|
||||
android:layout_height="@dimen/header_height"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:textSize="40sp"
|
||||
android:textSize="@dimen/time_input_text_size"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
android:cursorVisible="true"/>
|
||||
android:focusableInTouchMode="false"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
@ -31,13 +36,10 @@
|
||||
android:background="?android:listDivider"
|
||||
android:layout_below="@id/input"/>
|
||||
|
||||
<!-- TODO: Your height attr is being ignored because
|
||||
you constrained this below and above the header and
|
||||
footer views -->
|
||||
<com.philliphsu.clock2.editalarm.NumpadTimePicker
|
||||
android:id="@+id/number_grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="270dp"
|
||||
android:layout_height="@dimen/numpad_height"
|
||||
android:layout_below="@id/divider"/>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@ -11,4 +11,9 @@
|
||||
<dimen name="alarm_time_text_size">48sp</dimen>
|
||||
<dimen name="app_bar_height">180dp</dimen>
|
||||
<dimen name="text_margin">16dp</dimen>
|
||||
|
||||
<!-- NumpadTimePickerDialog -->
|
||||
<dimen name="header_height">72dp</dimen>
|
||||
<dimen name="numpad_height">270dp</dimen>
|
||||
<dimen name="time_input_text_size">40sp</dimen>
|
||||
</resources>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user