Open label dialog and time picker from ExpandedAlarmViewHolder
This commit is contained in:
parent
5ec512d268
commit
adb40beed8
@ -89,4 +89,8 @@ public class AddLabelDialog extends AppCompatDialogFragment {
|
|||||||
});
|
});
|
||||||
return alert;
|
return alert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnLabelSetListener(OnLabelSetListener l) {
|
||||||
|
mOnLabelSetListener = l;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,10 +6,8 @@ import android.media.RingtoneManager;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
import android.text.format.DateFormat;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -19,8 +17,7 @@ import com.philliphsu.clock2.AsyncAlarmsTableUpdateHandler;
|
|||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
import com.philliphsu.clock2.RecyclerViewFragment;
|
import com.philliphsu.clock2.RecyclerViewFragment;
|
||||||
import com.philliphsu.clock2.editalarm.BaseTimePickerDialog;
|
import com.philliphsu.clock2.editalarm.BaseTimePickerDialog;
|
||||||
import com.philliphsu.clock2.editalarm.NumberGridTimePickerDialog;
|
import com.philliphsu.clock2.editalarm.TimePickerHelper;
|
||||||
import com.philliphsu.clock2.editalarm.NumpadTimePickerDialog;
|
|
||||||
import com.philliphsu.clock2.model.AlarmCursor;
|
import com.philliphsu.clock2.model.AlarmCursor;
|
||||||
import com.philliphsu.clock2.model.AlarmsListCursorLoader;
|
import com.philliphsu.clock2.model.AlarmsListCursorLoader;
|
||||||
import com.philliphsu.clock2.util.AlarmController;
|
import com.philliphsu.clock2.util.AlarmController;
|
||||||
@ -34,7 +31,8 @@ public class AlarmsFragment extends RecyclerViewFragment<
|
|||||||
implements ScrollHandler, // TODO: Move interface to base class
|
implements ScrollHandler, // TODO: Move interface to base class
|
||||||
BaseTimePickerDialog.OnTimeSetListener {
|
BaseTimePickerDialog.OnTimeSetListener {
|
||||||
private static final String TAG = "AlarmsFragment";
|
private static final String TAG = "AlarmsFragment";
|
||||||
private static final String TAG_TIME_PICKER = "time_picker";
|
|
||||||
|
static final String TAG_TIME_PICKER = "time_picker";
|
||||||
|
|
||||||
// TODO: Delete these constants. We no longer use EditAlarmActivity.
|
// TODO: Delete these constants. We no longer use EditAlarmActivity.
|
||||||
// @Deprecated
|
// @Deprecated
|
||||||
@ -118,23 +116,7 @@ public class AlarmsFragment extends RecyclerViewFragment<
|
|||||||
// If we keep a reference to the dialog, we keep its previous state as well.
|
// If we keep a reference to the dialog, we keep its previous state as well.
|
||||||
// So the next time we call show() on it, the input field will show the
|
// So the next time we call show() on it, the input field will show the
|
||||||
// last inputted time.
|
// last inputted time.
|
||||||
BaseTimePickerDialog dialog = null;
|
BaseTimePickerDialog dialog = TimePickerHelper.newDialog(getActivity(), this);
|
||||||
String numpadStyle = getString(R.string.number_pad);
|
|
||||||
String gridStyle = getString(R.string.grid_selector);
|
|
||||||
String prefTimePickerStyle = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString(
|
|
||||||
// key for the preference value to retrieve
|
|
||||||
getString(R.string.key_time_picker_style),
|
|
||||||
// default value
|
|
||||||
numpadStyle);
|
|
||||||
if (prefTimePickerStyle.equals(numpadStyle)) {
|
|
||||||
dialog = NumpadTimePickerDialog.newInstance(this);
|
|
||||||
} else if (prefTimePickerStyle.equals(gridStyle)) {
|
|
||||||
dialog = NumberGridTimePickerDialog.newInstance(
|
|
||||||
this, // OnTimeSetListener
|
|
||||||
0, // Initial hour of day
|
|
||||||
0, // Initial minute
|
|
||||||
DateFormat.is24HourFormat(getActivity()));
|
|
||||||
}
|
|
||||||
// DISREGARD THE LINT WARNING ABOUT DIALOG BEING NULL.
|
// DISREGARD THE LINT WARNING ABOUT DIALOG BEING NULL.
|
||||||
dialog.show(getFragmentManager(), TAG_TIME_PICKER);
|
dialog.show(getFragmentManager(), TAG_TIME_PICKER);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import android.content.res.ColorStateList;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.SwitchCompat;
|
import android.support.v7.widget.SwitchCompat;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@ -14,10 +16,14 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.philliphsu.clock2.AddLabelDialog;
|
||||||
import com.philliphsu.clock2.Alarm;
|
import com.philliphsu.clock2.Alarm;
|
||||||
import com.philliphsu.clock2.BaseViewHolder;
|
import com.philliphsu.clock2.BaseViewHolder;
|
||||||
import com.philliphsu.clock2.OnListItemInteractionListener;
|
import com.philliphsu.clock2.OnListItemInteractionListener;
|
||||||
import com.philliphsu.clock2.R;
|
import com.philliphsu.clock2.R;
|
||||||
|
import com.philliphsu.clock2.editalarm.BaseTimePickerDialog;
|
||||||
|
import com.philliphsu.clock2.editalarm.BaseTimePickerDialog.OnTimeSetListener;
|
||||||
|
import com.philliphsu.clock2.editalarm.TimePickerHelper;
|
||||||
import com.philliphsu.clock2.editalarm.TimeTextUtils;
|
import com.philliphsu.clock2.editalarm.TimeTextUtils;
|
||||||
import com.philliphsu.clock2.util.AlarmController;
|
import com.philliphsu.clock2.util.AlarmController;
|
||||||
import com.philliphsu.clock2.util.AlarmUtils;
|
import com.philliphsu.clock2.util.AlarmUtils;
|
||||||
@ -38,11 +44,20 @@ import static com.philliphsu.clock2.util.DateFormatUtils.formatTime;
|
|||||||
*/
|
*/
|
||||||
public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
||||||
private static final String TAG = "BaseAlarmViewHolder";
|
private static final String TAG = "BaseAlarmViewHolder";
|
||||||
|
private static final String TAG_ADD_LABEL_DIALOG = "add_label_dialog";
|
||||||
|
|
||||||
private final AlarmController mAlarmController;
|
private final AlarmController mAlarmController;
|
||||||
// TODO: Should we use VectorDrawable type?
|
// TODO: Should we use VectorDrawable type?
|
||||||
private final Drawable mDismissNowDrawable;
|
private final Drawable mDismissNowDrawable;
|
||||||
private final Drawable mCancelSnoozeDrawable;
|
private final Drawable mCancelSnoozeDrawable;
|
||||||
|
private final FragmentManager mFragmentManager;
|
||||||
|
|
||||||
|
// These should only be changed from the OnTimeSet callback.
|
||||||
|
// If we had initialized these in onBind(), they would be reset to their original values
|
||||||
|
// from the Alarm each time the ViewHolder binds.
|
||||||
|
// A value of -1 indicates that the Alarm's time has not been changed.
|
||||||
|
int mSelectedHourOfDay = -1;
|
||||||
|
int mSelectedMinute = -1;
|
||||||
|
|
||||||
@Bind(R.id.time) TextView mTime;
|
@Bind(R.id.time) TextView mTime;
|
||||||
@Bind(R.id.on_off_switch) SwitchCompat mSwitch;
|
@Bind(R.id.on_off_switch) SwitchCompat mSwitch;
|
||||||
@ -58,6 +73,27 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
|||||||
// Instead, we create and cache the Drawables once.
|
// Instead, we create and cache the Drawables once.
|
||||||
mDismissNowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_dismiss_alarm_24dp);
|
mDismissNowDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_dismiss_alarm_24dp);
|
||||||
mCancelSnoozeDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_cancel_snooze);
|
mCancelSnoozeDrawable = ContextCompat.getDrawable(getContext(), R.drawable.ic_cancel_snooze);
|
||||||
|
|
||||||
|
// TODO: This is bad! Use a Controller/Presenter instead...
|
||||||
|
// or simply pass in an instance of FragmentManager to the ctor.
|
||||||
|
AppCompatActivity act = (AppCompatActivity) getContext();
|
||||||
|
mFragmentManager = act.getSupportFragmentManager();
|
||||||
|
|
||||||
|
// Are we recreating this because of a rotation?
|
||||||
|
// If so, try finding any dialog that was last shown in our backstack,
|
||||||
|
// and restore the callback.
|
||||||
|
BaseTimePickerDialog picker = (BaseTimePickerDialog)
|
||||||
|
mFragmentManager.findFragmentByTag(AlarmsFragment.TAG_TIME_PICKER);
|
||||||
|
if (picker != null) {
|
||||||
|
Log.i(TAG, "Restoring time picker callback");
|
||||||
|
picker.setOnTimeSetListener(newOnTimeSetListener());
|
||||||
|
}
|
||||||
|
AddLabelDialog labelDialog = (AddLabelDialog)
|
||||||
|
mFragmentManager.findFragmentByTag(TAG_ADD_LABEL_DIALOG);
|
||||||
|
if (labelDialog != null) {
|
||||||
|
Log.i(TAG, "Restoring add label callback");
|
||||||
|
labelDialog.setOnLabelSetListener(newOnLabelSetListener());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -149,7 +185,7 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
|||||||
Alarm alarm = getAlarm();
|
Alarm alarm = getAlarm();
|
||||||
alarm.setEnabled(checked);
|
alarm.setEnabled(checked);
|
||||||
if (alarm.isEnabled()) {
|
if (alarm.isEnabled()) {
|
||||||
// TODO: On Moto X, upcoming notification doesn't post immediately
|
// TODO: On 21+, upcoming notification doesn't post immediately
|
||||||
mAlarmController.scheduleAlarm(alarm, true);
|
mAlarmController.scheduleAlarm(alarm, true);
|
||||||
mAlarmController.save(alarm);
|
mAlarmController.save(alarm);
|
||||||
} else {
|
} else {
|
||||||
@ -162,7 +198,14 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
|||||||
|
|
||||||
@OnClick(R.id.time)
|
@OnClick(R.id.time)
|
||||||
void openTimePicker() {
|
void openTimePicker() {
|
||||||
Log.d(TAG, "Time clicked!");
|
BaseTimePickerDialog dialog = TimePickerHelper.newDialog(getContext(), newOnTimeSetListener());
|
||||||
|
dialog.show(mFragmentManager, AlarmsFragment.TAG_TIME_PICKER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.label)
|
||||||
|
void openLabelEditor() {
|
||||||
|
AddLabelDialog dialog = AddLabelDialog.newInstance(newOnLabelSetListener(), mLabel.getText());
|
||||||
|
dialog.show(mFragmentManager, TAG_ADD_LABEL_DIALOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindTime(Alarm alarm) {
|
private void bindTime(Alarm alarm) {
|
||||||
@ -217,4 +260,37 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
|
|||||||
boolean visible = label.length() > 0;
|
boolean visible = label.length() > 0;
|
||||||
bindLabel(visible, label);
|
bindLabel(visible, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AddLabelDialog.OnLabelSetListener newOnLabelSetListener() {
|
||||||
|
// Create a new listener per request. This is primarily used for
|
||||||
|
// setting the dialog callback again after a rotation.
|
||||||
|
//
|
||||||
|
// If we saved a reference to a listener, it would be tied to
|
||||||
|
// its ViewHolder instance. ViewHolders are reused, so we
|
||||||
|
// could accidentally leak this reference to other Alarm items
|
||||||
|
// in the list.
|
||||||
|
return new AddLabelDialog.OnLabelSetListener() {
|
||||||
|
@Override
|
||||||
|
public void onLabelSet(String label) {
|
||||||
|
mLabel.setText(label);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnTimeSetListener newOnTimeSetListener() {
|
||||||
|
// Create a new listener per request. This is primarily used for
|
||||||
|
// setting the dialog callback again after a rotation.
|
||||||
|
//
|
||||||
|
// If we saved a reference to a listener, it would be tied to
|
||||||
|
// its ViewHolder instance. ViewHolders are reused, so we
|
||||||
|
// could accidentally leak this reference to other Alarm items
|
||||||
|
// in the list.
|
||||||
|
return new OnTimeSetListener() {
|
||||||
|
@Override
|
||||||
|
public void onTimeSet(ViewGroup viewGroup, int hourOfDay, int minute) {
|
||||||
|
mSelectedHourOfDay = hourOfDay;
|
||||||
|
mSelectedMinute = minute;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -93,4 +93,9 @@ public class CollapsedAlarmViewHolder extends BaseAlarmViewHolder {
|
|||||||
setVisibility(mDays, visible);
|
setVisibility(mDays, visible);
|
||||||
mDays.setText(text);
|
mDays.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void openLabelEditor() {
|
||||||
|
// DO NOT IMPLEMENT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.media.RingtoneManager;
|
import android.media.RingtoneManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -15,7 +14,6 @@ import android.widget.Button;
|
|||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.ToggleButton;
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
import com.philliphsu.clock2.AddLabelDialog;
|
|
||||||
import com.philliphsu.clock2.Alarm;
|
import com.philliphsu.clock2.Alarm;
|
||||||
import com.philliphsu.clock2.DaysOfWeek;
|
import com.philliphsu.clock2.DaysOfWeek;
|
||||||
import com.philliphsu.clock2.OnListItemInteractionListener;
|
import com.philliphsu.clock2.OnListItemInteractionListener;
|
||||||
@ -27,6 +25,9 @@ import butterknife.Bind;
|
|||||||
import butterknife.OnCheckedChanged;
|
import butterknife.OnCheckedChanged;
|
||||||
import butterknife.OnClick;
|
import butterknife.OnClick;
|
||||||
|
|
||||||
|
import static com.philliphsu.clock2.DaysOfWeek.SATURDAY;
|
||||||
|
import static com.philliphsu.clock2.DaysOfWeek.SUNDAY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Phillip Hsu on 7/31/2016.
|
* Created by Phillip Hsu on 7/31/2016.
|
||||||
*/
|
*/
|
||||||
@ -64,8 +65,14 @@ public class ExpandedAlarmViewHolder extends BaseAlarmViewHolder {
|
|||||||
.ringtone(""/*TODO*/)
|
.ringtone(""/*TODO*/)
|
||||||
.vibrates(mVibrate.isChecked())
|
.vibrates(mVibrate.isChecked())
|
||||||
.build();
|
.build();
|
||||||
Log.d(TAG, "New alarm: " + newAlarm);
|
|
||||||
oldAlarm.copyMutableFieldsTo(newAlarm);
|
oldAlarm.copyMutableFieldsTo(newAlarm);
|
||||||
|
// ----------------------------------------------
|
||||||
|
// TOneverDO: precede copyMutableFieldsTo()
|
||||||
|
newAlarm.setEnabled(mSwitch.isChecked());
|
||||||
|
for (int i = SUNDAY; i <= SATURDAY; i++) {
|
||||||
|
newAlarm.setRecurring(i, isRecurringDay(i));
|
||||||
|
}
|
||||||
|
// ----------------------------------------------
|
||||||
listener.onListItemUpdate(newAlarm, getAdapterPosition());
|
listener.onListItemUpdate(newAlarm, getAdapterPosition());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -130,20 +137,6 @@ public class ExpandedAlarmViewHolder extends BaseAlarmViewHolder {
|
|||||||
((Activity) getContext()).startActivityForResult(intent, AlarmsFragment.REQUEST_PICK_RINGTONE);
|
((Activity) getContext()).startActivityForResult(intent, AlarmsFragment.REQUEST_PICK_RINGTONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.label) // The label view is in our superclass, but we can reference it.
|
|
||||||
void openLabelEditor() {
|
|
||||||
AddLabelDialog dialog = AddLabelDialog.newInstance(new AddLabelDialog.OnLabelSetListener() {
|
|
||||||
@Override
|
|
||||||
public void onLabelSet(String label) {
|
|
||||||
mLabel.setText(label);
|
|
||||||
// TODO: persist change. Use TimerController and its update()
|
|
||||||
}
|
|
||||||
}, mLabel.getText());
|
|
||||||
// TODO: This is bad! Use a Controller instead!
|
|
||||||
AppCompatActivity act = (AppCompatActivity) getContext();
|
|
||||||
dialog.show(act.getSupportFragmentManager(), "TAG");
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// We didn't have to write code like this in EditAlarmActivity, because we never committed
|
// We didn't have to write code like this in EditAlarmActivity, because we never committed
|
||||||
// any changes until the user explicitly clicked save. We have to do this here now because
|
// any changes until the user explicitly clicked save. We have to do this here now because
|
||||||
@ -204,4 +197,11 @@ public class ExpandedAlarmViewHolder extends BaseAlarmViewHolder {
|
|||||||
RingtoneManager.getActualDefaultRingtoneUri(getContext(), RingtoneManager.TYPE_ALARM)
|
RingtoneManager.getActualDefaultRingtoneUri(getContext(), RingtoneManager.TYPE_ALARM)
|
||||||
: Uri.parse(ringtone);
|
: Uri.parse(ringtone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isRecurringDay(int weekDay) {
|
||||||
|
// What position in the week is this day located at?
|
||||||
|
int pos = DaysOfWeek.getInstance(getContext()).positionOf(weekDay);
|
||||||
|
// Return the state of this day according to its button
|
||||||
|
return mDays[pos].isChecked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,41 @@
|
|||||||
|
package com.philliphsu.clock2.editalarm;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
|
||||||
|
import com.philliphsu.clock2.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by Phillip Hsu on 9/2/2016.
|
||||||
|
*
|
||||||
|
* Helper for creating a time picker dialog.
|
||||||
|
*/
|
||||||
|
public final class TimePickerHelper {
|
||||||
|
|
||||||
|
public static BaseTimePickerDialog newDialog(Context context, BaseTimePickerDialog.OnTimeSetListener l) {
|
||||||
|
BaseTimePickerDialog dialog = null;
|
||||||
|
String numpadStyle = context.getString(R.string.number_pad);
|
||||||
|
String gridStyle = context.getString(R.string.grid_selector);
|
||||||
|
String prefTimePickerStyle = PreferenceManager.getDefaultSharedPreferences(context).getString(
|
||||||
|
// key for the preference value to retrieve
|
||||||
|
context.getString(R.string.key_time_picker_style),
|
||||||
|
// default value
|
||||||
|
numpadStyle);
|
||||||
|
if (prefTimePickerStyle.equals(numpadStyle)) {
|
||||||
|
dialog = NumpadTimePickerDialog.newInstance(l);
|
||||||
|
} else if (prefTimePickerStyle.equals(gridStyle)) {
|
||||||
|
dialog = NumberGridTimePickerDialog.newInstance(
|
||||||
|
l, // OnTimeSetListener
|
||||||
|
0, // Initial hour of day
|
||||||
|
0, // Initial minute
|
||||||
|
DateFormat.is24HourFormat(context));
|
||||||
|
}
|
||||||
|
// We don't have a default case, because we don't need one; prefTimePickerStyle
|
||||||
|
// will ALWAYS match one of numpadStyle or gridStyle. As such, the dialog returned
|
||||||
|
// from here will NEVER be null.
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimePickerHelper() {}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user