From e0ddd0b70246f9a86f3ac49b4c113b02c4824d61 Mon Sep 17 00:00:00 2001 From: Phillip Hsu Date: Tue, 6 Sep 2016 19:50:05 -0700 Subject: [PATCH] Create AddLabelDialogController to manage showing and restoring AddLabelDialog --- .../clock2/AddLabelDialogController.java | 34 ++++++++++++++ .../clock2/alarms/BaseAlarmViewHolder.java | 47 +++++++------------ .../clock2/edittimer/EditTimerActivity.java | 29 ++++++------ .../clock2/timers/TimerViewHolder.java | 43 +++++------------ 4 files changed, 77 insertions(+), 76 deletions(-) create mode 100644 app/src/main/java/com/philliphsu/clock2/AddLabelDialogController.java diff --git a/app/src/main/java/com/philliphsu/clock2/AddLabelDialogController.java b/app/src/main/java/com/philliphsu/clock2/AddLabelDialogController.java new file mode 100644 index 0000000..50ea7ad --- /dev/null +++ b/app/src/main/java/com/philliphsu/clock2/AddLabelDialogController.java @@ -0,0 +1,34 @@ +package com.philliphsu.clock2; + +import android.support.v4.app.FragmentManager; +import android.util.Log; + +/** + * Created by Phillip Hsu on 9/6/2016. + */ +public final class AddLabelDialogController { + private static final String TAG = "add_label_dialog"; + + private final FragmentManager mFragmentManager; + private final AddLabelDialog.OnLabelSetListener mListener; + + public AddLabelDialogController(FragmentManager fragmentManager, AddLabelDialog.OnLabelSetListener listener) { + mFragmentManager = fragmentManager; + mListener = listener; + } + + public void show(CharSequence initialText) { + AddLabelDialog dialog = AddLabelDialog.newInstance(mListener, initialText); + dialog.show(mFragmentManager, TAG); +// show(dialog, TAG); + } + + // TODO: Rename to onConfigurationChange()? + public void tryRestoreCallback() { + AddLabelDialog labelDialog = (AddLabelDialog) mFragmentManager.findFragmentByTag(TAG); + if (labelDialog != null) { + Log.i(TAG, "Restoring add label callback"); + labelDialog.setOnLabelSetListener(mListener); + } + } +} diff --git a/app/src/main/java/com/philliphsu/clock2/alarms/BaseAlarmViewHolder.java b/app/src/main/java/com/philliphsu/clock2/alarms/BaseAlarmViewHolder.java index 2245f61..912e0e2 100644 --- a/app/src/main/java/com/philliphsu/clock2/alarms/BaseAlarmViewHolder.java +++ b/app/src/main/java/com/philliphsu/clock2/alarms/BaseAlarmViewHolder.java @@ -17,6 +17,7 @@ import android.widget.Button; import android.widget.TextView; import com.philliphsu.clock2.AddLabelDialog; +import com.philliphsu.clock2.AddLabelDialogController; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.BaseViewHolder; import com.philliphsu.clock2.OnListItemInteractionListener; @@ -45,9 +46,9 @@ import static com.philliphsu.clock2.util.DateFormatUtils.formatTime; */ public abstract class BaseAlarmViewHolder extends BaseViewHolder { private static final String TAG = "BaseAlarmViewHolder"; - private static final String TAG_ADD_LABEL_DIALOG = "add_label_dialog"; private final AlarmController mAlarmController; + private final AddLabelDialogController mAddLabelDialogController; // TODO: Should we use VectorDrawable type? private final Drawable mDismissNowDrawable; @@ -75,6 +76,19 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder { // or simply pass in an instance of FragmentManager to the ctor. AppCompatActivity act = (AppCompatActivity) getContext(); mFragmentManager = act.getSupportFragmentManager(); + mAddLabelDialogController = new AddLabelDialogController( + mFragmentManager, + new AddLabelDialog.OnLabelSetListener() { + @Override + public void onLabelSet(String label) { + final Alarm oldAlarm = getAlarm(); + Alarm newAlarm = oldAlarm.toBuilder() + .label(label) + .build(); + oldAlarm.copyMutableFieldsTo(newAlarm); + persistUpdatedAlarm(newAlarm, false); + } + }); // Are we recreating this because of a rotation? // If so, try finding any dialog that was last shown in our backstack, @@ -85,12 +99,7 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder { 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()); - } + mAddLabelDialogController.tryRestoreCallback(); } @Override @@ -202,8 +211,7 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder { @OnClick(R.id.label) void openLabelEditor() { - AddLabelDialog dialog = AddLabelDialog.newInstance(newOnLabelSetListener(), mLabel.getText()); - dialog.show(mFragmentManager, TAG_ADD_LABEL_DIALOG); + mAddLabelDialogController.show(mLabel.getText()); } /** @@ -274,27 +282,6 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder { 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) { - final Alarm oldAlarm = getAlarm(); - Alarm newAlarm = oldAlarm.toBuilder() - .label(label) - .build(); - oldAlarm.copyMutableFieldsTo(newAlarm); - persistUpdatedAlarm(newAlarm, false); - } - }; - } - private OnTimeSetListener newOnTimeSetListener() { // Create a new listener per request. This is primarily used for // setting the dialog callback again after a rotation. diff --git a/app/src/main/java/com/philliphsu/clock2/edittimer/EditTimerActivity.java b/app/src/main/java/com/philliphsu/clock2/edittimer/EditTimerActivity.java index d06a55d..084af8c 100644 --- a/app/src/main/java/com/philliphsu/clock2/edittimer/EditTimerActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/edittimer/EditTimerActivity.java @@ -11,6 +11,8 @@ import android.view.ViewGroup; import android.widget.EditText; import android.widget.TextView; +import com.philliphsu.clock2.AddLabelDialog; +import com.philliphsu.clock2.AddLabelDialogController; import com.philliphsu.clock2.BaseActivity; import com.philliphsu.clock2.R; @@ -20,7 +22,7 @@ import butterknife.OnLongClick; import butterknife.OnTouch; // TODO: Rename to CreateTimerActivity -public class EditTimerActivity extends BaseActivity { +public class EditTimerActivity extends BaseActivity implements AddLabelDialog.OnLabelSetListener { private static final int FIELD_LENGTH = 2; public static final String EXTRA_HOUR = "com.philliphsu.clock2.edittimer.extra.HOUR"; public static final String EXTRA_MINUTE = "com.philliphsu.clock2.edittimer.extra.MINUTE"; @@ -28,6 +30,8 @@ public class EditTimerActivity extends BaseActivity { public static final String EXTRA_LABEL = "com.philliphsu.clock2.edittimer.extra.LABEL"; public static final String EXTRA_START_TIMER = "com.philliphsu.clock2.edittimer.extra.START_TIMER"; + private AddLabelDialogController mAddLabelDialogController; + @Bind(R.id.edit_fields_layout) ViewGroup mEditFieldsLayout; @Bind(R.id.label) TextView mLabel; @Bind(R.id.hour) EditText mHour; @@ -39,13 +43,14 @@ public class EditTimerActivity extends BaseActivity { @Bind(R.id.focus_grabber) View mFocusGrabber; @Bind(R.id.fab) FloatingActionButton mFab; // Intentionally not using a (subclass of) GridLayoutNumpad, because - // it is expedient to refrain from adapting it for timers. + // it is expedient to not adapt it for timers. @Bind(R.id.numpad) GridLayout mNumpad; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); -// updateStartButtonVisibility(); + mAddLabelDialogController = new AddLabelDialogController(getSupportFragmentManager(), this); + mAddLabelDialogController.tryRestoreCallback(); } @Override @@ -64,6 +69,11 @@ public class EditTimerActivity extends BaseActivity { super.finish(); } + @Override + public void onLabelSet(String label) { + mLabel.setText(label); + } + @OnClick({ R.id.zero, R.id.one, R.id.two, R.id.three, R.id.four, R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine }) void onClick(TextView view) { @@ -144,7 +154,7 @@ public class EditTimerActivity extends BaseActivity { @OnClick(R.id.label) void openEditLabelDialog() { - // TODO: Show the edit label alert dialog. + mAddLabelDialogController.show(mLabel.getText()); } @OnClick(R.id.fab) @@ -169,15 +179,4 @@ public class EditTimerActivity extends BaseActivity { private EditText getFocusedField() { return (EditText) mEditFieldsLayout.findFocus(); } - -// private void updateStartButtonVisibility() { -// // TODO: parse the field's text to an integer and check > 0 instead? -// if (TextUtils.equals(mHour.getText(), "00") -// && TextUtils.equals(mMinute.getText(), "00") -// && TextUtils.equals(mSecond.getText(), "00")) { -// mFab.hide(); -// } else { -// mFab.show(); -// } -// } } diff --git a/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java b/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java index abf2d34..6096977 100644 --- a/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java +++ b/app/src/main/java/com/philliphsu/clock2/timers/TimerViewHolder.java @@ -2,7 +2,6 @@ package com.philliphsu.clock2.timers; import android.animation.ObjectAnimator; import android.graphics.drawable.Drawable; -import android.support.v4.app.FragmentManager; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.PopupMenu; @@ -15,6 +14,7 @@ import android.widget.SeekBar; import android.widget.TextView; import com.philliphsu.clock2.AddLabelDialog; +import com.philliphsu.clock2.AddLabelDialogController; import com.philliphsu.clock2.AsyncTimersTableUpdateHandler; import com.philliphsu.clock2.BaseViewHolder; import com.philliphsu.clock2.OnListItemInteractionListener; @@ -37,8 +37,8 @@ public class TimerViewHolder extends BaseViewHolder { private ObjectAnimator mProgressAnimator; private final Drawable mStartIcon; private final Drawable mPauseIcon; - private final FragmentManager mFragmentManager; private final PopupMenu mPopupMenu; + private final AddLabelDialogController mAddLabelDialogController; @Bind(R.id.label) TextView mLabel; @Bind(R.id.duration) CountdownChronometer mChronometer; @@ -59,17 +59,15 @@ public class TimerViewHolder extends BaseViewHolder { // 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. - AddLabelDialog labelDialog = (AddLabelDialog) - mFragmentManager.findFragmentByTag(TAG_ADD_LABEL_DIALOG); - if (labelDialog != null) { - Log.i(TAG, "Restoring add label callback"); - labelDialog.setOnLabelSetListener(newOnLabelSetListener()); - } + mAddLabelDialogController = new AddLabelDialogController( + act.getSupportFragmentManager(), + new AddLabelDialog.OnLabelSetListener() { + @Override + public void onLabelSet(String label) { + mController.updateLabel(label); + } + }); + mAddLabelDialogController.tryRestoreCallback(); // The item layout is inflated in the super ctor, so we can safely reference our views. mPopupMenu = new PopupMenu(getContext(), mMenuButton); @@ -117,8 +115,7 @@ public class TimerViewHolder extends BaseViewHolder { @OnClick(R.id.label) void openLabelEditor() { - AddLabelDialog dialog = AddLabelDialog.newInstance(newOnLabelSetListener(), mLabel.getText()); - dialog.show(mFragmentManager, TAG_ADD_LABEL_DIALOG); + mAddLabelDialogController.show(mLabel.getText()); } @OnClick(R.id.menu) @@ -198,20 +195,4 @@ public class TimerViewHolder extends BaseViewHolder { } mSeekBar.getThumb().mutate().setAlpha(timeRemaining <= 0 ? 0 : 255); } - - 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 Timer items - // in the list. - return new AddLabelDialog.OnLabelSetListener() { - @Override - public void onLabelSet(String label) { - mController.updateLabel(label); - } - }; - } }