Как правильно закрыть Alert Dialog в Android? - PullRequest
2 голосов
/ 24 февраля 2012

Я использую следующий код, чтобы показать пользователю базовый текстовый ввод.

В первый раз все работает отлично.Однако во второй раз, когда я вызываю диалоговое окно, приложение вылетает.

Я подозреваю, что это потому, что я не уничтожаю EditText, который я добавил в представление.Так что ... для тех, кто намного опытнее меня ... как правильно справиться с этим?

Ниже у вас есть мой код и LogCat

final EditText ipInput = new EditText(this);
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setView(ipInput);
    builder.setTitle("Enter Server IP Address: ");
    builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            //STORE IP ADDRESS
        }
    });

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            //CANCELLED
        }
    });
    builder.create();

И "шоу-ing ":

settings.setOnClickListener(new OnClickListener(){
        public void onClick(View view){
            builder.show();
        }
    });

Трассировка стека:

02-24 02:08:55.759: E/AndroidRuntime(582): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.view.ViewGroup.addViewInner(ViewGroup.java:3011)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.view.ViewGroup.addView(ViewGroup.java:2900)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.view.ViewGroup.addView(ViewGroup.java:2880)
02-24 02:08:55.759: E/AndroidRuntime(582):  at com.android.internal.app.AlertController.setupView(AlertController.java:401)
02-24 02:08:55.759: E/AndroidRuntime(582):  at com.android.internal.app.AlertController.installContent(AlertController.java:241)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.app.AlertDialog.onCreate(AlertDialog.java:314)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.app.Dialog.dispatchOnCreate(Dialog.java:335)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.app.Dialog.show(Dialog.java:248)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.app.AlertDialog$Builder.show(AlertDialog.java:907)
02-24 02:08:55.759: E/AndroidRuntime(582):  at pirelli.app.ScanBarcode$4.onClick(ScanBarcode.java:90)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.view.View.performClick(View.java:3110)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.view.View$PerformClick.run(View.java:11934)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.os.Handler.handleCallback(Handler.java:587)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.os.Handler.dispatchMessage(Handler.java:92)
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.os.Looper.loop(Looper.java:132)  
02-24 02:08:55.759: E/AndroidRuntime(582):  at android.app.ActivityThread.main(ActivityThread.java:4123)
02-24 02:08:55.759: E/AndroidRuntime(582):  at java.lang.reflect.Method.invokeNative(Native Method)
02-24 02:08:55.759: E/AndroidRuntime(582):  at java.lang.reflect.Method.invoke(Method.java:491)
02-24 02:08:55.759: E/AndroidRuntime(582):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
02-24 02:08:55.759: E/AndroidRuntime(582):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
02-24 02:08:57.150: I/Process(582): Sending signal. PID: 582 SIG: 9

Ответы [ 3 ]

6 голосов
/ 24 февраля 2012

На мой взгляд, проблема не столько в окончательности Alarm Dialog Builder, сколько в Button.Таким образом, я изменил ваш код:

   private Context ctx;
   AlertDialog.Builder builder;
   EditText ipInput ;

  settings.setOnClickListener(new OnClickListener(){
         ipInput = new EditText(ctx);
         builder.setView(ipInput);
         builder.show();    
       }
   });

(изменил «окончательность» как компоновщика, так и EditText и заново создал EditText для каждого вызова).Я инициализировал и контекст, и конструктор в OnCreate:

    ctx = this.getApplicationContext();
    builder =   new AlertDialog.Builder(this);
3 голосов
/ 24 февраля 2012

попробуйте позвонить:

onClick(...){
    dialog.dismiss();
}
//and
onClick(...){
    dialog.cancel();
}

отклонение - обычно положительная кнопка, а отмена - обычно отрицательная кнопка, но это ваше дело.Вы также можете реализовать onDismissListener или onCancelListener для получения обратных вызовов, где бы этот диалог не создавался.

Кроме того,

builder.create(); 

возвращает указатель на диалоговое окно, которое он создает.Таким образом, вы можете сказать:

Dialog mDialog = builder.create();

и затем вызывать методы в mDialog.

3 голосов
/ 24 февраля 2012

Проблема в том, что вы пытаетесь дважды прикрепить один и тот же AlertDialog в Activity, попробуйте каждый раз создавать новый или вызывать Activity.removeDialog (int), прежде чем присоединять один и тот же, ознакомьтесь с официальным руководством разработчика здесь :

Если вы используете onCreateDialog (int) для управления состоянием ваших диалогов (как обсуждалось в предыдущем разделе), то каждый раз, когда ваш диалог закрывается, состояние объекта Dialog сохраняется Activity. Если вы решите, что вам больше не нужен этот объект или важно, чтобы состояние было очищено, то вы должны вызвать removeDialog (int). Это удалит все внутренние ссылки на объект, и если диалоговое окно отобразится, оно отклонит его.

Рекомендуется всегда управлять созданием диалогов в методе обратного вызова Activity.onCreateDialog (), как указано здесь :

protected Dialog onCreateDialog(int id) {
  Dialog dialog;
  switch(id) {
    case DIALOG_PAUSED_ID:
      // do the work to define the pause Dialog
      break;
    case DIALOG_GAMEOVER_ID:
      // do the work to define the game over Dialog
      break;
    default:
      dialog = null;
  }
  return dialog;
}
...