すべてのリクエストで変更される可能性がある1つのオプションを使用して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();
}
アクティビティのremoveDialog(int)関数を使用することもできます。ダイアログが閉じられると、アクティビティは基本的にダイアログの状態を保存します(想像上のパフォーマンス上の理由から)。ダイアログでremoveDialog(int)を呼び出すと、アクティビティはダイアログのすべての参照を強制的にアンロードし、表示されている場合は画面から閉じます。
ダイアログが表示される前に呼び出される 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;
}
}
これはこの質問の重複です: Android:AlertDialogに表示されるテキストを変更できません
次のようにすることもできます: http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html
ただし、長押しメニューの表示が遅くなるようです...
上記の一貫性のない動作を修正したと思います。ダイアログを最初に作成するとき(それがAlertDialog.Builderの場合)、メッセージを初期状態(null以外)に設定する必要があります。そうしないと、onPrepareDialogが意図した値でメッセージを上書きしません。したがって、ダイアログを作成するときは、次のようにして常にメッセージにnull以外の値を含めるようにしてください。私はこれに何日も苦労し、この解決策を偶然見つけました:
AlertDialog.Builder resultAlert = new AlertDialog.Builder(context);
if ( message == null ) {
resultAlert.setMessage("");
} else {
resultAlert.setMessage(message);
}
カスタムダイアログがある場合は、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" />
アクティビティ管理ダイアログを使用するパフォーマンス上の理由は理解していますが、単純な場合を除いて使用しないことをお勧めします。この理由は次のとおりです。
Bundle引数はAPIレベル8でのみ追加されたため、下位互換性のために採用することはできません。これは事実上、「onPrepareDialog」が状態の違いについて非ローカル変数に依存する必要があることを意味します。
練習では、「onPrepareDialog」の本体で行われたダイアログの変更に応じて、動作が不十分で一貫性がないことを示しています。
ダイアログがサブクラス化され、必要に応じて作成される場合、これらの問題は発生しません。 'setOwnerActivity'は、必要に応じて呼び出すことができます。