我正在使用以下代码向用户显示基本的文本框输入。
第一次一切都很好。但是,第二次调用对话框时,应用程序崩溃了。
我怀疑这是因为我没有销毁我添加到View中的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();
和“show-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 :(得分:6)
我看到它的方式,问题不在于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);
答案 1 :(得分:3)
问题是你试图在Activity中附加相同的AlertDialog两次,每次尝试创建一个或在附加同一个之前调用Activity.removeDialog(int),查看官方开发指南here:
如果使用onCreateDialog(int)来管理对话框的状态(如上一节所述),那么每次关闭对话框时,Activity都会保留Dialog对象的状态。如果您决定不再需要此对象,或者清除状态很重要,那么您应该调用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;
}
答案 2 :(得分:3)
尝试致电:
onClick(...){
dialog.dismiss();
}
//and
onClick(...){
dialog.cancel();
}
解雇通常正面按钮,取消通常是 否定按钮,但这取决于你。您还可以实现onDismissListener或onCancelListener,以便在创建此对话框的任何位置获取回调。
此外,
builder.create();
返回指向它实例化的对话框的指针。所以,你可以说:
Dialog mDialog = builder.create();
然后在mDialog上调用方法。