I'm build my app with Mortar + Flow. I'm trying to figure out the correct way to show a popup that requests some text from the user. I've created this popup class:
public class SavedPageTitleInputPopup implements Popup<SavedPageTitleInput, Optional<String>> {
private final Context context;
private AlertDialog dialog;
public SavedPageTitleInputPopup(Context context) {
this.context = context;
}
@Override public Context getContext() {
return context;
}
@Override
public void show(final SavedPageTitleInput info, boolean withFlourish,
final PopupPresenter<SavedPageTitleInput, Optional<String>> presenter) {
if (dialog != null) throw new IllegalStateException("Already showing, can't show " + info);
final EditText input = new EditText(context);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
input.setText(info.savedPage.getName());
dialog = new AlertDialog.Builder(context).setTitle(info.title)
.setView(input)
.setMessage(info.body)
.setPositiveButton(info.confirm, new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface d, int which) {
dialog = null;
final String newTitle = Strings.emptyToNull(String.valueOf(input.getText()));
presenter.onDismissed(Optional.fromNullable(newTitle));
}
})
.setNegativeButton(info.cancel, new DialogInterface.OnClickListener() {
@Override public void onClick(DialogInterface d, int which) {
dialog = null;
presenter.onDismissed(Optional.<String>absent());
}
})
.setCancelable(true)
.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override public void onCancel(DialogInterface d) {
dialog = null;
presenter.onDismissed(Optional.<String>absent());
}
})
.show();
}
@Override public boolean isShowing() {
return dialog != null;
}
@Override public void dismiss(boolean withFlourish) {
dialog.dismiss();
dialog = null;
}
}
This class works as expected. It uses the SavedPage
to figure out what to display in the dialog and it returns the users input to the PopupPresenter
using PopupPresenter#onDismissed when the correct button is pressed.
My problem is writing the PopupPresenter
subclass used to present the dialog and process the input. This is what I have right now:
new PopupPresenter<SavedPage, Optional<String>>() {
@Override protected void onPopupResult(Optional<String> result) {
if (result.isPresent()) {
// The user entered something, so update the API
// Oh wait, I don't have a reference to the SavedPage
// that was displayed in the dialog!
}
}
}
As the comments say, I don't have a reference to the SavedPage
that was displayed in the dialog. It was stored in the whatToShow
field in PopupPresenter
, but this field is nulled out right before onPopupResult
is called. It seems like I would be unnecessarily repeating myself to keep an additional copy of the SavedPage
.
There isn't a lot of documentation yet on PopupPresenter and Popup. The only thing I have seen is a basic example in the sample project. They create a ConfirmerPopup based on data within the Confirmation object. The purpose of the ConfirmerPopup is to capture a boolean decision from the user based on the title/body given to the Confirmation object as seen by the class declaration.
In your case you want to capture additional user inputted text from the user. When PopupPresenter#onPopupResult is called the result object should contain all of the data needed from SavedPageTitleInputPopup. Modify your SavedPageTitleInputPopup as follows
Your PopupPresenter doesn't need to know anything about the Dialog's implementation now.