Create AddLabelDialogController to manage showing and restoring AddLabelDialog

This commit is contained in:
Phillip Hsu 2016-09-06 19:50:05 -07:00
parent 51469fa282
commit e0ddd0b702
4 changed files with 77 additions and 76 deletions

View File

@ -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);
}
}
}

View File

@ -17,6 +17,7 @@ import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import com.philliphsu.clock2.AddLabelDialog; import com.philliphsu.clock2.AddLabelDialog;
import com.philliphsu.clock2.AddLabelDialogController;
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;
@ -45,9 +46,9 @@ 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;
private final AddLabelDialogController mAddLabelDialogController;
// TODO: Should we use VectorDrawable type? // TODO: Should we use VectorDrawable type?
private final Drawable mDismissNowDrawable; private final Drawable mDismissNowDrawable;
@ -75,6 +76,19 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
// or simply pass in an instance of FragmentManager to the ctor. // or simply pass in an instance of FragmentManager to the ctor.
AppCompatActivity act = (AppCompatActivity) getContext(); AppCompatActivity act = (AppCompatActivity) getContext();
mFragmentManager = act.getSupportFragmentManager(); 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? // Are we recreating this because of a rotation?
// If so, try finding any dialog that was last shown in our backstack, // If so, try finding any dialog that was last shown in our backstack,
@ -85,12 +99,7 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
Log.i(TAG, "Restoring time picker callback"); Log.i(TAG, "Restoring time picker callback");
picker.setOnTimeSetListener(newOnTimeSetListener()); picker.setOnTimeSetListener(newOnTimeSetListener());
} }
AddLabelDialog labelDialog = (AddLabelDialog) mAddLabelDialogController.tryRestoreCallback();
mFragmentManager.findFragmentByTag(TAG_ADD_LABEL_DIALOG);
if (labelDialog != null) {
Log.i(TAG, "Restoring add label callback");
labelDialog.setOnLabelSetListener(newOnLabelSetListener());
}
} }
@Override @Override
@ -202,8 +211,7 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
@OnClick(R.id.label) @OnClick(R.id.label)
void openLabelEditor() { void openLabelEditor() {
AddLabelDialog dialog = AddLabelDialog.newInstance(newOnLabelSetListener(), mLabel.getText()); mAddLabelDialogController.show(mLabel.getText());
dialog.show(mFragmentManager, TAG_ADD_LABEL_DIALOG);
} }
/** /**
@ -274,27 +282,6 @@ public abstract class BaseAlarmViewHolder extends BaseViewHolder<Alarm> {
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) {
final Alarm oldAlarm = getAlarm();
Alarm newAlarm = oldAlarm.toBuilder()
.label(label)
.build();
oldAlarm.copyMutableFieldsTo(newAlarm);
persistUpdatedAlarm(newAlarm, false);
}
};
}
private OnTimeSetListener newOnTimeSetListener() { private OnTimeSetListener newOnTimeSetListener() {
// Create a new listener per request. This is primarily used for // Create a new listener per request. This is primarily used for
// setting the dialog callback again after a rotation. // setting the dialog callback again after a rotation.

View File

@ -11,6 +11,8 @@ import android.view.ViewGroup;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import com.philliphsu.clock2.AddLabelDialog;
import com.philliphsu.clock2.AddLabelDialogController;
import com.philliphsu.clock2.BaseActivity; import com.philliphsu.clock2.BaseActivity;
import com.philliphsu.clock2.R; import com.philliphsu.clock2.R;
@ -20,7 +22,7 @@ import butterknife.OnLongClick;
import butterknife.OnTouch; import butterknife.OnTouch;
// TODO: Rename to CreateTimerActivity // TODO: Rename to CreateTimerActivity
public class EditTimerActivity extends BaseActivity { public class EditTimerActivity extends BaseActivity implements AddLabelDialog.OnLabelSetListener {
private static final int FIELD_LENGTH = 2; private static final int FIELD_LENGTH = 2;
public static final String EXTRA_HOUR = "com.philliphsu.clock2.edittimer.extra.HOUR"; public static final String EXTRA_HOUR = "com.philliphsu.clock2.edittimer.extra.HOUR";
public static final String EXTRA_MINUTE = "com.philliphsu.clock2.edittimer.extra.MINUTE"; 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_LABEL = "com.philliphsu.clock2.edittimer.extra.LABEL";
public static final String EXTRA_START_TIMER = "com.philliphsu.clock2.edittimer.extra.START_TIMER"; 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.edit_fields_layout) ViewGroup mEditFieldsLayout;
@Bind(R.id.label) TextView mLabel; @Bind(R.id.label) TextView mLabel;
@Bind(R.id.hour) EditText mHour; @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.focus_grabber) View mFocusGrabber;
@Bind(R.id.fab) FloatingActionButton mFab; @Bind(R.id.fab) FloatingActionButton mFab;
// Intentionally not using a (subclass of) GridLayoutNumpad, because // 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; @Bind(R.id.numpad) GridLayout mNumpad;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// updateStartButtonVisibility(); mAddLabelDialogController = new AddLabelDialogController(getSupportFragmentManager(), this);
mAddLabelDialogController.tryRestoreCallback();
} }
@Override @Override
@ -64,6 +69,11 @@ public class EditTimerActivity extends BaseActivity {
super.finish(); 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, @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 }) R.id.five, R.id.six, R.id.seven, R.id.eight, R.id.nine })
void onClick(TextView view) { void onClick(TextView view) {
@ -144,7 +154,7 @@ public class EditTimerActivity extends BaseActivity {
@OnClick(R.id.label) @OnClick(R.id.label)
void openEditLabelDialog() { void openEditLabelDialog() {
// TODO: Show the edit label alert dialog. mAddLabelDialogController.show(mLabel.getText());
} }
@OnClick(R.id.fab) @OnClick(R.id.fab)
@ -169,15 +179,4 @@ public class EditTimerActivity extends BaseActivity {
private EditText getFocusedField() { private EditText getFocusedField() {
return (EditText) mEditFieldsLayout.findFocus(); 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();
// }
// }
} }

View File

@ -2,7 +2,6 @@ package com.philliphsu.clock2.timers;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
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.app.AppCompatActivity;
import android.support.v7.widget.PopupMenu; import android.support.v7.widget.PopupMenu;
@ -15,6 +14,7 @@ import android.widget.SeekBar;
import android.widget.TextView; import android.widget.TextView;
import com.philliphsu.clock2.AddLabelDialog; import com.philliphsu.clock2.AddLabelDialog;
import com.philliphsu.clock2.AddLabelDialogController;
import com.philliphsu.clock2.AsyncTimersTableUpdateHandler; import com.philliphsu.clock2.AsyncTimersTableUpdateHandler;
import com.philliphsu.clock2.BaseViewHolder; import com.philliphsu.clock2.BaseViewHolder;
import com.philliphsu.clock2.OnListItemInteractionListener; import com.philliphsu.clock2.OnListItemInteractionListener;
@ -37,8 +37,8 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
private ObjectAnimator mProgressAnimator; private ObjectAnimator mProgressAnimator;
private final Drawable mStartIcon; private final Drawable mStartIcon;
private final Drawable mPauseIcon; private final Drawable mPauseIcon;
private final FragmentManager mFragmentManager;
private final PopupMenu mPopupMenu; private final PopupMenu mPopupMenu;
private final AddLabelDialogController mAddLabelDialogController;
@Bind(R.id.label) TextView mLabel; @Bind(R.id.label) TextView mLabel;
@Bind(R.id.duration) CountdownChronometer mChronometer; @Bind(R.id.duration) CountdownChronometer mChronometer;
@ -59,17 +59,15 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
// TODO: This is bad! Use a Controller/Presenter instead... // TODO: This is bad! Use a Controller/Presenter instead...
// or simply pass in an instance of FragmentManager to the ctor. // or simply pass in an instance of FragmentManager to the ctor.
AppCompatActivity act = (AppCompatActivity) getContext(); AppCompatActivity act = (AppCompatActivity) getContext();
mFragmentManager = act.getSupportFragmentManager(); mAddLabelDialogController = new AddLabelDialogController(
act.getSupportFragmentManager(),
// Are we recreating this because of a rotation? new AddLabelDialog.OnLabelSetListener() {
// If so, try finding any dialog that was last shown in our backstack, @Override
// and restore the callback. public void onLabelSet(String label) {
AddLabelDialog labelDialog = (AddLabelDialog) mController.updateLabel(label);
mFragmentManager.findFragmentByTag(TAG_ADD_LABEL_DIALOG);
if (labelDialog != null) {
Log.i(TAG, "Restoring add label callback");
labelDialog.setOnLabelSetListener(newOnLabelSetListener());
} }
});
mAddLabelDialogController.tryRestoreCallback();
// The item layout is inflated in the super ctor, so we can safely reference our views. // The item layout is inflated in the super ctor, so we can safely reference our views.
mPopupMenu = new PopupMenu(getContext(), mMenuButton); mPopupMenu = new PopupMenu(getContext(), mMenuButton);
@ -117,8 +115,7 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
@OnClick(R.id.label) @OnClick(R.id.label)
void openLabelEditor() { void openLabelEditor() {
AddLabelDialog dialog = AddLabelDialog.newInstance(newOnLabelSetListener(), mLabel.getText()); mAddLabelDialogController.show(mLabel.getText());
dialog.show(mFragmentManager, TAG_ADD_LABEL_DIALOG);
} }
@OnClick(R.id.menu) @OnClick(R.id.menu)
@ -198,20 +195,4 @@ public class TimerViewHolder extends BaseViewHolder<Timer> {
} }
mSeekBar.getThumb().mutate().setAlpha(timeRemaining <= 0 ? 0 : 255); 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);
}
};
}
} }