2012-02-24 93 views
2

我正在使用下面的代碼向用戶顯示基本的文本框輸入。如何在Android中正確關閉警報對話框?

第一次一切正常。但是,我第二次調用對話框時,應用程序崩潰。

我懷疑這是因爲我沒有銷燬我添加到視圖中的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 
+0

請將完整的錯誤日誌發佈在受影響的代碼行旁邊。 – Mannaz 2012-02-24 00:28:31

+0

添加完整的錯誤日誌。感謝您抽出時間:D – Eugen 2012-02-24 00:35:38

回答

6

我看到它的方式,問題不在於Alarm對話框生成器的終結點,而在於按鈕的問題。我正是如此改變你的代碼:

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

太棒了!感謝上百萬的花時間。這真的很有幫助,我認爲這是最優雅的方式。 – Eugen 2012-02-25 15:46:15

3

問題是你試圖在一個活動中附加相同的AlertDialog兩次,嘗試每次創建一個新的或者在附加同一個Activity之前調用Activity.removeDialog(int),ch埃克了官方開發指南here

如果您正在使用onCreateDialog(INT)來管理對話框的狀態(如在上一節中討論),然後每次你的對話框被駁回,對話的狀態對象由Activity保留。如果你決定不再需要這個對象或重要的是狀態被清除,那麼你應該調用removeDialog(int)。這將刪除對象的任何內部引用,並且如果該對話框正在顯示,它將消除它。

最好的做法是始終管理Activity.onCreateDialog您創建對話框()回調方法,指出here

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; 
} 
3

嘗試調用:

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

解僱是通常陽性按鈕和取消是通常是負面的按鈕,但它取決於你。您也可以實現onDismissListener或onCancelListener以在創建此對話框時獲取回調。

此外,

builder.create(); 

返回一個指向它實例對話框。所以,你可以說:

Dialog mDialog = builder.create(); 

然後調用mDialog上的方法。