Android - 指定的孩子已经有父母。你必须先调用孩子父母的removeView()
我知道有几十个问题会问这个错误,但是没有一个提出的解决方案似乎适用于我的问题,至少我知道。Android - 指定的孩子已经有父母。你必须先调用孩子父母的removeView()
这里是我的日志:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:1976)
at android.view.ViewGroup.addView(ViewGroup.java:1871)
at android.view.ViewGroup.addView(ViewGroup.java:1851)
at com.android.internal.app.AlertController.setupView(AlertController.java:365)
at com.android.internal.app.AlertController.installContent(AlertController.java:206)
at android.app.AlertDialog.onCreate(AlertDialog.java:251)
at android.app.Dialog.dispatchOnCreate(Dialog.java:307)
at android.app.Dialog.show(Dialog.java:225)
at com.company.MyApp.MyActivity$7.onItemClick(MyActivity.java:240)
at android.widget.AdapterView.performItemClick(AdapterView.java:284)
at android.widget.ListView.performItemClick(ListView.java:3513)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:1812)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
这里是MyActivity.java的onCreate()。你可以看到一个Dialog Builder被显示并给出了一些值。无论myDialogLayout
和myDialogBuilder
是私有类成员
@Override
public void onCreate(Bundle savedInstanceState)
{
// ... a bunch of init code...
// Create a dialog builder
myDialogLayout = getLayoutInflater().inflate(R.layout.leaving, null);
myDialogBuilder = new AlertDialog.Builder(this)
.setTitle("My Title")
.setView(myDialogLayout)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which) {}
});
// ... more code ...
}
后来,当某个按钮被点击我的活动中,myDialogBuilder
定制了一下,然后创建一个对话框并显示。 myDialog
是私有类变量/成员:
// Builder customized a bit
myDialogBuilder
.setMessage("custom message here");
// Dialog created from Builder
myDialog = myDialogBuilder.create();
// Dialog shown
myDialog.show(); // <---- MyActivity.java Line: 240
所以,在我的问题,当我点击我的按钮,创建成功的对话框。但是当我按下对话框上的取消并再次按下按钮后,我看到日志中显示的错误。出于某种原因,该活动不希望我重用我的myDialog
对话框。它是一个班级成员,因此可以从onClick
处理程序访问它。而且每次单击该按钮时,myDialog
都是一个新的对话框,因为它每次都是从头开始创建的myDialogBuilder.create()
。
任何人都知道问题是什么?我也尝试在按下“取消”按钮时添加myDialog.dismiss()
,但这没有什么区别。
此外,您可以在我的myDialogBuilder
中看到自定义XML布局用于对话框的视图。根据错误消息,它听起来像是希望我使用removeView()
以删除在对话框中使用的视图。但myDialogBuilder.removeView()
不是一个有效的方法。
是myDialogLayout
一个类的成员变量?如果是这样,那么从第一次显示对话框时就已经有了一个父对象,然后创建第二个对话框,该对话框也试图成为myDialogLayout
的父对象。尝试在每次打开对话框时创建myDialogLayout
的新实例。
这是为什么建议使用onCreateDialog()onPrepareDialog()方法的一个主要例子。
如果每次按下按钮时都要实例化myDialog,则会尝试将先前创建的对话框对象(旧父对象)的视图附加到新对话框。
已经实例化,显示和排除的对话只需要再次显示,而不是完全重新创建。
假设myDialog是一个类成员,请尝试检查myDialog是否为null。如果不为null,则再次显示而不是完全实例化它。
编辑 - 下面是我的意思,使用onPrepareDialog()和onCreateDialog()的例子。在Create创建对话框,并且每次显示时,都会对其进行准备,并通过使用findViewById并清除文本来获取EditText引用。我们在这里假设DIALOG_TEST是一个整数常量,在layout/dialog_test.xml中有一个EditText视图,它带有id edittext。
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
switch(id){
case DIALOG_TEST:
EditText mEditText = (EditText) dialog.findViewById(R.id.edittext);
mEditText.setText("");
break;
}
}
@Override
protected Dialog onCreateDialog(int id) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
switch(id){
case DIALOG_TEST:
LinearLayout layout = (LinearLayout) ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.dialog_test, null);
builder.setTitle("Enter Something").setView(layout);
return builder.create();
}
}
对话需要被创建,因为它的消息(和其他方面)每次都不同。 – 2012-02-06 22:00:59
对话框有一个findViewById方法。您应该使用它来获取对视图的引用,然后对其进行更新。 – Maximus 2012-02-06 22:05:45
是的,我意识到这一点。我也在每次改变正面按钮的'onClick'行为。我在上面的原文中没有提到这个,所以我可以简化这个例子。 – 2012-02-06 22:45:16
这是关键。我将'myDialogLayout'从一个类成员变量中移除,并将其放在'onClick'处理程序方法的本地。那样的话,这是一种每次都会膨胀的新布局。谢谢! – 2012-02-06 22:04:18