web-dev-qa-db-ja.com

Androidすべてのリクエストで動的に変化するテキストを含むAlertDialog

すべてのリクエストで変更される可能性がある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();
}
25
Ulrich Scheller

アクティビティのremoveDialog(int)関数を使用することもできます。ダイアログが閉じられると、アクティビティは基本的にダイアログの状態を保存します(想像上のパフォーマンス上の理由から)。ダイアログでremoveDialog(int)を呼び出すと、アクティビティはダイアログのすべての参照を強制的にアンロードし、表示されている場合は画面から閉じます。

ダイアログの作成
Activity#removeDialog(int)

19
Andrew Burgess

ダイアログが表示される前に呼び出される 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;
  }
}
33
JaanusSiim

これはこの質問の重複です: Android:AlertDialogに表示されるテキストを変更できません

次のようにすることもできます: http://andmobidev.blogspot.com/2010/03/modifying-alert-dialogs-list-items.html

ただし、長押しメニューの表示が遅くなるようです...

4
kenyee

上記の一貫性のない動作を修正したと思います。ダイアログを最初に作成するとき(それがAlertDialog.Builderの場合)、メッセージを初期状態(null以外)に設定する必要があります。そうしないと、onPrepareDialogが意図した値でメッセージを上書きしません。したがって、ダイアログを作成するときは、次のようにして常にメッセージにnull以外の値を含めるようにしてください。私はこれに何日も苦労し、この解決策を偶然見つけました:

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

if ( message == null ) {
    resultAlert.setMessage("");
} else {
    resultAlert.setMessage(message);
}
4
Jerry Destremps

カスタムダイアログがある場合は、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" />
1
BubbaGum

アクティビティ管理ダイアログを使用するパフォーマンス上の理由は理解していますが、単純な場合を除いて使用しないことをお勧めします。この理由は次のとおりです。

  1. Bundle引数はAPIレベル8でのみ追加されたため、下位互換性のために採用することはできません。これは事実上、「onPrepareDialog」が状態の違いについて非ローカル変数に依存する必要があることを意味します。

  2. 練習では、「onPrepareDialog」の本体で行われたダイアログの変更に応じて、動作が不十分で一貫性がないことを示しています。

ダイアログがサブクラス化され、必要に応じて作成される場合、これらの問題は発生しません。 'setOwnerActivity'は、必要に応じて呼び出すことができます。

1
user527897