2012-02-06 3 views
9

나는이 오류에 관해 묻는 수십 가지 질문을 알고 있지만 제안 된 해결책 중 어느 것도 내 문제에 적용되지 않는 것으로 보인다.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()이다. 대화 상자 빌더가 표시되고 몇 가지 값이 있음을 알 수 있습니다. 두 myDialogLayoutmyDialogBuilder 개인 클래스 멤버
@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 조금을 정의하고 다음 대화 상자가 생성되어 표시됩니다

있습니다.
// 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는 전용 클래스 변수/회원입니다. 하지만 대화 상자에서 취소를 누른 다음 버튼을 다시 누르면 로그에 오류가 표시됩니다. 어떤 이유로 활동에서 내 myDialog 대화 상자를 다시 사용하고 싶지 않습니다. 클래스 멤버이므로 onClick 핸들러에서 액세스 할 수 있습니다. myDialog은 매번 myDialogBuilder.create()에 의해 처음부터 새로 만들어 졌기 때문에 버튼을 클릭 할 때마다 새로운 대화 상자가됩니다.

누구나 무슨 문제인지 알고 계십니까? 취소 버튼을 누를 때 myDialog.dismiss()을 추가하려고 시도했지만 차이가 없습니다.

또한 내 myDialogBuilder에서 사용자 지정 XML 레이아웃이 대화보기에 사용됨을 알 수 있습니다. 오류 메시지에 따르면 대화 상자에서보기가 사용되지 않도록하려면 removeView()을 사용하기를 원합니다. 그러나 myDialogBuilder.removeView()은 유효한 방법이 아닙니다.

답변

17

myDialogLayout입니다. 클래스 멤버 변수는? 그렇다면 대화 상자를 처음 표시 한 때부터 이미 부모가 있으므로 보조자 대화 상자가 만들어져 myDialogLayout의 부모가됩니다. 대화 상자를 열 때마다 myDialogLayout의 새 인스턴스를 만들어보십시오.

+2

열쇠가되었습니다.클래스 멤버 변수가 아닌 myDialogLayout을 제거하고 대신'onClick' 핸들러 메소드를 로컬로 만들었습니다. 그렇게하면 매번 팽창되는 새로운 레이아웃이됩니다. 감사! –

3

이것은 onCreateDialog() onPrepareDialog() 메서드를 사용하는 것이 가장 좋은 이유 중 하나입니다.

버튼을 누를 때마다 myDialog를 인스턴스화하면 이전에 작성된 대화 상자 객체 (이전 상위)의보기를 새 대화 상자에 첨부하려고합니다.

인스턴스화, 보임 및 해제 된 대화 상자는 다시 표시 할 필요가 있으며 완전히 다시 작성하지 않아도됩니다.

myDialog가 클래스 멤버라고 가정하고 myDialog is null인지 먼저 확인하십시오. null가 아닌 경우, 인스턴스를 완전하게 인스턴스화하는 것이 아니라, 다시 표시합니다.

EDIT - 다음은 onPrepareDialog() 및 onCreateDialog()를 사용하여 의미하는 예입니다. 생성시 대화 상자가 만들어지고 표시 될 때마다 준비되고 EditViewById를 사용하여 EditText 참조를 얻고 텍스트를 지 웁니다. 여기서 가정합니다. DIALOG_TEST는 정수이고, layout/dialog_test.xml에는 id가 edittext 인 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(); 
    } 
} 
+0

대화 상자는 메시지 (및 다른 측면)가 매번 달라지기 때문에 만들어야합니다. –

+0

대화 상자에는 findViewById 메소드가 있습니다. 이를 사용하여 뷰에 대한 참조를 얻은 다음이를 업데이트해야합니다. – Maximus

+0

그래, 나는 그 사실을 알고있다. 나는 또한 매번 긍정적 인 버튼에 대한'onClick' 행동을 바꾸고 있습니다. 위의 원본 게시물에서이를 언급하지 않았으므로 예제를 단순화 할 수 있습니다. –

관련 문제