25

我想显示一个带有一个选项的 AlertDialog,该选项可能会随每个请求而改变。因此,例如,有一次我想显示“添加到联系人”选项,而另一次应该是“从联系人中删除”。

我的代码第一次确实可以工作,但是 Android 似乎缓存了 AlertDialog 以便下次不会执行 onCreateDialog 。因此选项不再改变。我可以阻止这种缓存,还是有另一种更改选项的方法?

我正在使用 SDK 1.5,但使用的是 1.1。

@Override
protected Dialog onCreateDialog(final int id) {
    ...
    String add_remove_contact = res.getString(R.string.profile_add_to_contacts);
    if (user.getContacts().contains(profileID)) {
        add_remove_contact = res.getString(R.string.profile_remove_from_contacts);
        // TODO: this string is not changed when contact status changes 
    }
    final CharSequence[] items = {res.getString(R.string.view_profile),
                                  res.getString(R.string.profile_send_message),
                                  add_remove_contact};
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    ...
    return builder.create();
}
4

8 回答 8

34

查看将在显示对话框之前调用的onPrepareDialog方法。在那里您可以根据请求类型更改所需的值。

日期选择器示例

@Override
protected Dialog onCreateDialog(final int id) {
  switch (id) {
  case DIALOG_DATE_ID:
    final Calendar c = Calendar.getInstance();
    return new DatePickerDialog(this, this, c.get(Calendar.YEAR),
                                c.get(Calendar.MONTH), 
                                c.get(Calendar.DAY_OF_MONTH));
  default:
    return super.onCreateDialog(id);
  }
}

@Override
protected void onPrepareDialog(final int id, final Dialog dialog) {
  switch (id) {
  case DIALOG_DATE_ID:
    //update to current time
    final Calendar c = Calendar.getInstance();
    ((DatePickerDialog) dialog).updateDate(c.get(Calendar.YEAR), 
                                           c.get(Calendar.MONTH), 
                                           c.get(Calendar.DAY_OF_MONTH));
    break;
  }
}
于 2009-06-05T09:23:32.763 回答
19

您还可以使用 Activity 的removeDialog(int)函数。当对话框被关闭时,Activity 基本上存储对话框的状态(出于性能原因,我想)。在对话框上调用removeDialog(int)会强制活动卸载对话框的所有引用,并在显示时将其从屏幕上关闭。

创建对话框
活动#removeDialog(int)

于 2009-06-09T19:13:59.700 回答
4

这是这个问题的重复: Android:无法更改 AlertDialog 中出现的文本

您也可以这样做: http ://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html

似乎确实减慢了长按菜单的显示速度......

于 2010-06-06T01:09:40.623 回答
4

我想我已经解决了上述不一致的行为。最初创建对话框时(当它仍然是 AlertDialog.Builder 时),您必须将消息设置为初始状态(非空),否则 onPrepareDialog 不会用预期值覆盖它。因此,当您创建对话框时,请执行以下操作以在消息中始终包含非空值。我为此苦苦挣扎了好几天,偶然发现了这个解决方案:

AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);

if ( message == null ) {
    resultAlert.setMessage("");
} else {
    resultAlert.setMessage(message);
}
于 2011-10-31T20:36:39.157 回答
2

当您有自定义对话框时,您可以使用 dialog.getWindow().findViewById(...) 更改自定义项

此示例保存最后显示的文本,并在下次显示对话框时再次显示。

// custom dialog
final Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.customized);

dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
    @Override
    public void onDismiss(DialogInterface dialogInterface) {
       EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
       savedText = dialogText.getText();
    }
});

dialog.show();
EditText dialogText = (EditText)dialog.getWindow().findViewById(R.id.customText);
dialogText.setText(savedText);

自定义对话框的 xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<Button
    android:id="@+id/buttonOK"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="OK"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_marginBottom="16dp" />

<EditText
    android:id="@+id/customText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="19dp"
    android:hint="Message"
    android:ems="10"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true" />

于 2016-12-02T08:29:38.890 回答
1

我了解使用活动管理对话框的性能原因,但建议不要使用它们,除非是简单的情况。原因如下:

  1. Bundle 参数仅在 API 级别 8 中添加,因此不能用于向后兼容。这实际上意味着“onPrepareDialog”需要依赖非局部变量来实现状态差异;

  2. 实践表明,响应“onPrepareDialog”主体中所做的任何对话框更改的行为不佳且不一致。

如果 Dialogs 被子类化并根据需要创建,则不会出现这些困难。如有必要,可以调用“setOwnerActivity”。

于 2010-12-03T12:34:14.800 回答
-1

我有一个想法,但不是很好。*这在用户不经常使用对话框时使用!*解决方法:首先,你应该声明一个变量(int类型)并将默认值设置为0。例如private int i=0; ,在使用Activity的showDialog方法之前,增加int变量i并将值i作为参数发布为showDialog方法。代码可能像这样

private int i=0;

//before you show the dialog
this.i++;
this.showDialog(this.i);
于 2011-11-16T11:46:12.330 回答
-3

确切地。对于使用 w/ 创建的 AlertDialog,它Builder.create()onPrepareDialog()无用的。Builder 是单向的,一旦创建了对话框,就无法更新。我的意思是不能松散,我相信您可以处理视图并手动完成所有操作,但这首先破坏了使用构建器的意义。

我找到的唯一解决方案是手动创建/显示/关闭对话框而不是使用onCreateDialog(),showDialog()等。我尝试调用removeDialog(),但这似乎不起作用。

于 2009-10-26T07:52:46.330 回答