5

我正在使用Mortar + Flow构建我的应用程序。我试图找出正确的方法来显示一个向用户请求一些文本的弹出窗口。我创建了这个弹出类:

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

此类按预期工作。它使用SavedPage来确定要在对话框中显示的内容,并在按下正确的按钮时将用户输入返回给PopupPresenterusing PopupPresenter#onDismissed 。

我的问题是编写PopupPresenter用于呈现对话框和处理输入的子类。这就是我现在所拥有的:

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!
    }
  }
}

正如评论所说,我没有引用SavedPage对话框中显示的内容。它存储在 中的whatToShow字段中PopupPresenter,但在调用之前该字段被清空onPopupResult。似乎我会不必要地重复自己以保留SavedPage.

4

1 回答 1

0

PopupPresenterPopup上还没有很多文档。我唯一看到的是示例项目中的一个基本示例。他们根据Confirmation对象中的数据创建一个ConfirmerPopup 。ConfirmerPopup 的目的是根据类声明所见的 Confirmation 对象的标题/正文从用户那里捕获布尔决策。

public class ConfirmerPopup implements Popup<Confirmation, Boolean> {

在您的情况下,您希望从用户那里捕获其他用户输入的文本。当调用 PopupPresenter#onPopupResult 时,结果对象应包含 SavedPageTitleInputPopup 所需的所有数据。修改您的 SavedPageTitleInputPopup 如下

public class SavedPageTitleInputPopup implements Popup<SavedPage, SavedPageResults> {
  private final Context context;
  private AlertDialog dialog;

  public SavedPageTitleInputPopup(Context context) {
    this.context = context;
  }

  @Override public Context getContext() {
    return context;
  }

  @Override
  public void show(SavedPage info, boolean withFlourish, final PopupPresenter<SavedPage, SavedPageResults> presenter) {
    if (dialog != null) throw new IllegalStateException("Already showing, can't show " + info);
    // Create your Dialog but scrape all user data within OnClickListeners
    final AlertDialog.Builder builder = new AlertDialog.Builder(context);
    //Anything else you need to do... .setView() or .setTitle() for example
    builder.setPositiveButton(info.confirm, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface d, int which) {
        dialog = null;
        //Save data to SavedPageResults
        final SavedPageResults results = new SavedPageResults():
        presenter.onDismissed(results);
      }
    });
    builder.setNegativeButton(info.cancel, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface d, int which) {
        dialog = null;
        final SavedPageResults results = new SavedPageResults();
        presenter.onDismissed(results);
      }
    });
    dialog = builder.show();
  }

  @Override public boolean isShowing() {
    return dialog != null;
  }

  @Override public void dismiss(boolean withFlourish) {
    dialog.dismiss();
    dialog = null;
  }
}  

现在,您的 PopupPresenter 不需要了解有关 Dialog 的实现的任何信息。

new PopupPresenter<SavedPage, SavedPageResults>() {
  @Override protected void onPopupResult(SavedPageResults result) {
    if (result.isPresent()) {
      updateUi(result.getSavedText());  
    }
  }
}
于 2014-05-05T13:16:46.097 回答