Java Android AlertDialog 在每个请求上动态更改文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/954726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android AlertDialog with dynamically changing text on every request
提问by Ulrich Scheller
I want to show an AlertDialog with one option that might change on every request. So for example at one time I want to show the option "add to contacts" while another time it should be "remove from contacts".
我想显示一个带有一个选项的 AlertDialog,该选项可能会随着每个请求而改变。因此,例如,有一次我想显示“添加到联系人”选项,而另一次应该是“从联系人中删除”。
My code does work on the first time, however Android seems to cache the AlertDialog so that onCreateDialog is not executed next time. Therefore the option doesnt change anymore. Can I prevent this caching, or is there just another way of changing the option?
我的代码在第一次运行时确实有效,但是 Android 似乎缓存了 AlertDialog,以便下次不会执行 onCreateDialog。因此该选项不再改变。我可以阻止这种缓存,还是只有另一种更改选项的方法?
I am working with SDK 1.5 but using 1.1.
我正在使用 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();
}
采纳答案by Andrew Burgess
You can also use the removeDialog(int)function of the Activity. When a dialog is dismissed, the Activity basically stores the state of the dialog (for performance reasons I would imagine). Calling removeDialog(int)on the dialog forces the activity to unload all references for the dialog and dismisses it from the screen if it's being shown.
您还可以使用Activity的removeDialog(int)函数。当对话框被关闭时,Activity 基本上存储了对话框的状态(出于性能原因,我可以想象)。在对话框上调用removeDialog(int) 会强制 Activity 卸载对话框的所有引用,并在显示对话框时将其从屏幕上消除。
回答by JaanusSiim
Take a look at onPrepareDialogmethod that will be called before dialog is shown. There You can change the required values based on request type.
查看将在显示对话框之前调用的onPrepareDialog方法。在那里您可以根据请求类型更改所需的值。
Example with date picker
日期选择器示例
@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;
}
}
回答by Jeffrey Blattman
exactly. for AlertDialog, that was created w/ Builder.create()
, onPrepareDialog()
is useless. Builder is one-way in that once the dialog is created, you can't update. i mean can't loosely, i am sure you could get a handle to the view and do it all manually, but that defeats the point of using the builder in the first place.
确切地。对于AlertDialog,已创建瓦特/ Builder.create()
,onPrepareDialog()
是没用的。Builder 是一种方式,一旦创建对话框,您就无法更新。我的意思是不能松散地,我相信你可以获得视图的句柄并手动完成所有操作,但这首先破坏了使用构建器的意义。
the only solution i found was to manually create / show / dismiss the dialog instead of using onCreateDialog()
, showDialog()
, etc. i tried calling removeDialog()
, but that did not seem to work.
我发现的唯一的解决办法是手动创建/显示/关闭该对话框,而不是使用onCreateDialog()
,showDialog()
等我打过电话removeDialog()
,但是这似乎并没有工作。
回答by kenyee
This is a dup of this question: Android: Can not change the text appears in AlertDialog
这是这个问题的重复: Android:无法更改出现在 AlertDialog 中的文本
You can also do it this way: http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html
你也可以这样做:http: //andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html
Does seem to slow down the display of the longpress menu though...
虽然似乎减慢了长按菜单的显示速度......
回答by user527897
I understand the performance reasons for using activity managed dialogs, but would recommend that they are not used except for simple cases. The reasons for this are:
我了解使用活动管理对话框的性能原因,但建议除了简单的情况外不要使用它们。原因如下:
The Bundle argument was only added in API Level 8, so can't be adopted for backwards compatibility. This effectively means that 'onPrepareDialog' needs to rely on non-local variables for state differences;
Practice indicates poor and inconsistent behaviour in response to any dialog changes made in the body of 'onPrepareDialog'.
Bundle 参数仅在 API 级别 8 中添加,因此不能采用以实现向后兼容性。这实际上意味着“onPrepareDialog”需要依赖非局部变量来处理状态差异;
实践表明响应在“onPrepareDialog”主体中所做的任何对话框更改时行为不佳且不一致。
None of these difficulties arise if Dialogs are subclassed and created as needed. 'setOwnerActivity' can be called if necessary.
如果根据需要对 Dialogs 进行子类化和创建,则不会出现这些困难。如有必要,可以调用“setOwnerActivity”。
回答by Jerry Destremps
I think I have a fix for the inconsistent behavior mentioned above. When initially creating the dialog (when it's still an AlertDialog.Builder), you have to set the message to an initial state (not null) or onPrepareDialog will NOT overwrite it with the intended value. So when you're creating the dialog, do something like this to always have a non-null value in the message. I struggled with this for days and found this solution by accident:
我想我已经解决了上述不一致的行为。最初创建对话框时(当它仍然是 AlertDialog.Builder)时,您必须将消息设置为初始状态(非空),否则 onPrepareDialog 不会用预期值覆盖它。因此,当您创建对话框时,请执行以下操作以使消息中始终具有非空值。我为此苦苦挣扎了好几天,偶然发现了这个解决方案:
AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);
if ( message == null ) {
resultAlert.setMessage("");
} else {
resultAlert.setMessage(message);
}
回答by androidyue
And I got a idea but not so good.*This is used when the users don't use the dialog quite frequently!*The solution :first,you should declare a variable (int type) and make the default value as 0.such as private int i=0;
and before you use the showDialog methods of Activity,increase the int variable i and post the value i as the parameter as showDialog method.
the code may like this
我有一个想法,但不太好。*当用户不经常使用对话框时使用!*解决方法:首先,你应该声明一个变量(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);
回答by BubbaGum
When you have a custom dialog you can change custom items by using dialog.getWindow().findViewById(...)
当您有自定义对话框时,您可以使用 dialog.getWindow().findViewById(...) 更改自定义项
This example save the last text shown and display it again the next time you show the dialog.
本示例保存最后显示的文本,并在您下次显示对话框时再次显示。
// 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);
Customized dialog's xml:
自定义对话框的 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" />