2009-06-05 19 views
22

AlertDialogを表示するには、リクエストごとに変更される可能性がある1つのオプションが必要です。たとえば、一度に「連絡先に追加」オプションを表示したい場合は、「連絡先から削除」する必要があります。Android AlertDialogでリクエストごとに動的にテキストが変更される

私のコードは初めて動作しますが、Androidは次回にonCreateDialogを実行しないようにAlertDialogをキャッシュしているようです。したがって、オプションはもう変わりません。このキャッシングを防ぐことはできますか、またはオプションを変更する別の方法がありますか?

私は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(); 
} 

答えて

19

また、活動のremoveDialog(int型)機能を使用することができます。ダイアログが終了すると、Activityは基本的にダイアログの状態を保存します(私が想像するパフォーマンス上の理由から)。 ダイアログのremoveDialog(int)を呼び出すと、アクティビティはダイアログのすべての参照をアンロードし、表示されている場合はそれを画面から削除します。正確

Creating Dialogs
Activity#removeDialog(int)

+9

パフォーマンス上の理由から、ダイアログは一度作成する必要があります(比較的高価な操作です)。毎回isを再作成するのではなく、onPrepareDialogメソッドを使用して、表示されているようにダイアログを変更することができます(次の解説の説明を参照)。 – ChrisV

+0

まだここに来ている人にとって、 'removeDialog'と' showDialog'は廃止予定です。 Androidが 'Fragments'に移行したので、' DialogFragment'の使用が推奨されました。詳細については、公式のドキュメントへのリンクがあります:http://developer.android.com/reference/android/app/DialogFragment.html –

+0

「removeDialog」は推奨されていません。ちょうど... –

33

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

onPrepareDialogは、ダイアログを更新するには良い場所です。しかし、どうすればonPrepareDialogのAlertDialogs項目を変更できますか?このためのメソッドはないようで、findViewByIdで使用するidを見つけることはできません。 –

+3

ダイアログが引数として渡されるので、 "findViewById"は必要ありません。 "setMessage"のようなAlertDialog固有のメソッドを使用する場合は、それをキャストする必要があります。 –

+0

1年以上後、このコードが「うまくいく」ことがわかりました。あなたは実際にそれを微調整する必要はありません!ありがとうございました。私はAndroidの開発ガイドを見ましたが、onPrepareDialogを完全に使用する方法はほとんど分かりません。あなたの例は素晴らしい仕事でした。 – davidcesarino

-3

。 AlertDialogの場合は、Builder.create()と書かれており、onPrepareDialog()は役に立たない。 Builderは、一度ダイアログが作成されると、更新することができない一方向です。私はゆるくすることはできません、私はあなたがビューのハンドルを取得し、それをすべて手動で行うことができると確信していますが、それは最初の場所でビルダーを使用する点を敗北させる。私が見つけた唯一の解決策は、手動で代わりonCreateDialog()showDialog()を使用してのダイアログを閉じ/ /ショーを作成することでした

、など私はremoveDialog()を呼び出してみましたが、それは動作していないようでした。

+6

それは間違っています。指定したDialogをAlertDialogのようなより具体的な型にキャストすると、setMessageを使ってメッセージのようなプロパティを更新することができます。 –

1
...しかしlongpressメニューの表示を遅くするように見えるん

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

  1. バンドル引数が唯一のAPIレベル8で追加されましたので、後方互換性のために採用することはできません。これは事実上、 'onPrepareDialog'が状態の違いに非ローカル変数に依存する必要があることを意味します。

  2. 実際には、 'onPrepareDialog'の本文で行われたダイアログの変更に応答して、動作が矛盾していないことを示しています。

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

4

私は上記の一貫性のない動作の修正があると思います。最初にダイアログを作成するとき(まだAlertDialog.Builderの場合)、メッセージを初期状態(nullではない)に設定するか、onPrepareDialogは意図した値で上書きしません。したがって、ダイアログを作成するときは、メッセージに常にnull以外の値を持つような操作を行います。私は日のためにこれと格闘し、事故によって、この解決策を見つけた:

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

if (message == null) { 
    resultAlert.setMessage(""); 
} else { 
    resultAlert.setMessage(message); 
} 
+0

あなたは正しいです。このバグはここで追跡されています:https://code.google.com/p/android/issues/detail?id=6489 – TalkLittle

-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); 
+3

あなたが言うように、これはあまり良くありません。 :)このアプローチは不要で無駄です。次回に新しいダイアログを新しく作成する場合は、removeDialog()を使用する必要があります。 –

0

カスタムダイアログを持っている場合は、あなたが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" /> 

関連する問題