2015-01-21 14 views
66

W mojej aplikacji muszę często przełączać się między dwoma układami. Błąd występuje w układzie zamieszczonym poniżej.Określone dziecko już ma rodzica. Musisz najpierw wywołać removeView() na rodzicu dziecka (Android)

Gdy mój układ jest wywoływany po raz pierwszy, nie występuje żaden błąd i wszystko jest w porządku. Kiedy następnie wywołać inny układ (pusty jeden), a potem zadzwonić mój układ po raz drugi, to daje mi następujący błąd:

> FATAL EXCEPTION: main 
>  java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 

Mój układ Kod wygląda następująco:

tv = new TextView(getApplicationContext()); // are initialized somewhere else 
    et = new EditText(getApplicationContext()); // in the code 


private void ConsoleWindow(){ 
     runOnUiThread(new Runnable(){ 

    @Override 
    public void run(){ 

     // MY LAYOUT: 
     setContentView(R.layout.activity_console); 
     // LINEAR LAYOUT 
     LinearLayout layout=new LinearLayout(getApplicationContext()); 
     layout.setOrientation(LinearLayout.VERTICAL); 
     setContentView(layout); 

     // TEXTVIEW 
     layout.addView(tv); // <========== ERROR IN THIS LINE DURING 2ND RUN 
     // EDITTEXT 
     et.setHint("Enter Command"); 
     layout.addView(et); 
     } 
    } 
} 

Wiem, że to pytanie było już wcześniej zadawane, ale nie pomogło mi to w moim przypadku.

Odpowiedz

197

Komunikat o błędzie informuje, co należy zrobić.

// TEXTVIEW 
if(tv.getParent()!=null) 
    ((ViewGroup)tv.getParent()).removeView(tv); // <- fix 
layout.addView(tv); // <========== ERROR IN THIS LINE DURING 2ND RUN 
// EDITTEXT 
23

Przyszedłem tutaj, wyszukując błąd z moim recyclerview, ale rozwiązanie nie działa (oczywiście). Napisałem przyczynę i rozwiązanie tego problemu w przypadku recydywy. Mam nadzieję, że to komuś pomaga.

Błąd jest spowodowany jeśli w onCreateViewHolder() następujący sposób następuje:

layoutInflater = LayoutInflater.from(context); 
return new VH(layoutInflater.inflate(R.layout.single_row, parent)); 

Zamiast tego powinno być

return new VH(layoutInflater.inflate(R.layout.single_row, null)); 
+3

Czasami losowe odpowiedzi, które nie są dokładnie odpowiedzi na zadawane pytania, pomoc kogoś innego. To działało dla mnie. Dzięki! –

+0

Miło !, i dlatego ludzie powinni przeważnie podawać "null" jako parametry 2d w inflaters. Dzięki. – superUser

+1

Podanie wartości zerowej do parametru odpowiedzialnego za rodzica nie jest złym pomysłem, ale trzeba wiedzieć, że w tym przypadku widok podrzędny (ten, który się zawyża), nie będzie w stanie samodzielnie zmierzyć go w niektórych przypadkach, ponieważ nie wiem nic o rodzicu. W niektórych przypadkach będzie działać, ale w niektórych nie. – Sniper

0

Znalazłem kolejną poprawkę:

if (mView.getParent() == null) { 
        myDialog = new Dialog(MainActivity.this); 
        myDialog.setContentView(mView); 
        createAlgorithmDialog(); 
       } else { 
        createAlgorithmDialog(); 
       } 

Oto ja wystarczy, że instrukcja if sprawdzi, czy widok miał rodzica i czy nie utworzył nowego dialo g, ustaw contentView i pokaż okno dialogowe w mojej metodzie "createAlgorithmDialog()".

Ustawia również przyciski dodatnie i ujemne (przyciski OK i Anuluj) w górę za pomocą onClickListeners.

1

W moim przypadku problem został spowodowany przez fakt, że nadmuchałem nadrzędny widok przy użyciu układu <merge>. W tym przypadku błąd spowodował błąd addView().

View to_add = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, true); 
// parent_layout.addView(to_add); // THIS CAUSED THE CRASH 

Usuwanie addView() pomogły rozwiązać problem.

7

prostu przekazać argument attachtoroot jako fałszywą

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false); 
Powiązane problemy