指定的子项已经有了父级。您必须先在子项的父级上调用removeView()。

19

我有一个用于创建对话框的类,并编写了获取其中值的代码。当我尝试第二次调用对话框时,它会出现以下错误信息:

: java.lang.IllegalStateException: 指定的子元素已经有一个父元素。您首先必须在子元素的父元素上调用 removeView()。

请问怎样才能移除这个 removeView() 呢?

下面是该类的代码:

    package com.util;

import android.app.AlertDialog;  
import android.content.Context;  
import android.content.DialogInterface;  
import android.content.DialogInterface.OnClickListener;  
import android.widget.EditText;  

/** 
 * helper for Prompt-Dialog creation 
 */  
public abstract class PromptDialog extends AlertDialog.Builder implements OnClickListener {  
 private final EditText input;  

 /** 
  * @param context 
  * @param title resource id 
  * @param message resource id 
  */  
 public PromptDialog(Context context, int title, int message) {  
  super(context);  
  setTitle(title);
  //:TODO Display msg only if not empty
  //setMessage(message);  

  input = new EditText(context);  
  setView(input);  

  setPositiveButton("ok", this);  
  setNegativeButton("cancel", this);  
 }  

 /** 
  * will be called when "cancel" pressed. 
  * closes the dialog. 
  * can be overridden. 
  * @param dialog 
  */  
 public void onCancelClicked(DialogInterface dialog) {  
  dialog.dismiss();  
 }  

 @Override  
 public void onClick(DialogInterface dialog, int which) {  
  if (which == DialogInterface.BUTTON_POSITIVE) {  
   if (onOkClicked(input.getText().toString())) {  
    dialog.dismiss();  
   }  
  } else {  
   onCancelClicked(dialog);  
  }  
 }  

 /** 

      * called when "ok" pressed. 
      * @param input 
      * @return true, if the dialog should be closed. false, if not. 
      */  
     abstract public boolean onOkClicked(String input);  
    }  

下面是调用该类实例的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



final PromptDialog dlgName = new PromptDialog(this, R.string.enterName, R.string.enter_comment) {  
             @Override  
             public boolean onOkClicked(String input) {  
              // do something 
              mName = input;
                  save();
                          //end do some thing
              return true; // true = close dialog  
             }  
        };      


    mTxtShiftName = (TextView) findViewById(R.id.shiftname);
            mTxtShiftName.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dlgName.show();
            }   
        });

你在第二次尝试时又调用了对话框构造函数吗? - C.d.
我在问题中使用的所有代码都是复制的。我认为这可能是原因。但我不知道如何避免这种情况? - SAN
当您单击按钮时,请勿两次调用构造函数。在onCreate中使用Dialog构造函数或在onPrepareDailog中使用代码创建对话框,然后只需在想要显示它时调用dialog.show()。 - C.d.
以上代码位于onCreate中。我已经编辑了上面的代码。它被调用在mTxtShiftName.setOnClickListener中。这样做有问题吗?提前致谢。 - SAN
3个回答

66

在我的fragment的onCreateView()方法中,我调用了错误的inflate方法导致出现了这个错误。

我通过将代码更改为以下内容来解决该问题:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_saves, container);
}

变成这样:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_saves, container, false);
}

1

您应该将调用对话框构造函数的代码放在onCreateDialog(int)回调方法中,而不是onCreate(Bundle)中。在您的代码中,当您调用dlgName.show()时,对话框会隐式初始化。因此,当您第二次调用对话框时,也是使用对话框构造函数。


0

看看这个:

http://developer.android.com/reference/android/view/LayoutInflater.html#inflate(int,android.view.ViewGroup,boolean)

具体来说,是LayoutInflator的inflate方法中的布尔参数和返回值:

返回值 充气层次结构的根视图。 如果提供了root并且attachToRoot为true,则这是root; 否则它是充气XML文件的根。

View dialogView = inflater.inflate(R.layout.brush_opts_dialog, rootView, false);

您想让充气视图的根视图成为创建的视图,而不是“this”,这将是活动内整个片段。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接