2015-01-21 26 views
66

Nella mia app, devo passare frequentemente da un layout all'altro. L'errore sta accadendo nel layout pubblicato qui sotto.Il figlio specificato ha già un genitore. Devi chiamare removeView() sul genitore del bambino per primo (Android)

Quando il mio layout viene chiamato la prima volta, non si verificano errori e tutto va bene. Quando poi ho chiamo un layout diverso (uno vuoto) e poi chiamo il mio layout per la seconda volta, mi dà il seguente errore:

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

mio layout codice simile a questo:

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); 
     } 
    } 
} 

So che questa domanda è stata fatta prima, ma non è stata d'aiuto nel mio caso.

risposta

197

Il messaggio di errore dice cosa dovresti fare.

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

sono venuto qui a cercare l'errore con la mia recyclerview ma la soluzione non ha funzionato (ovviamente). Ho scritto la causa e la soluzione per questo in caso di riciclaggio di rifiuti. Spero che aiuti qualcuno.

L'errore è causato se nella onCreateViewHolder() il seguente metodo viene seguito:

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

Invece dovrebbe essere

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

risposte volte casuali che non sono esattamente le risposte ai quesiti sottoposti aiutare qualcun altro. Questo ha funzionato per me. Grazie! –

+0

Bello !, ed è per questo che la gente dovrebbe per lo più passare "nullo" come parametro 2d negli inflatori. Grazie. – superUser

+1

Passare Null al parametro responsabile per il genitore non è una cattiva idea, ma devi sapere che in questo caso la vista figlio (quella che si gonfia) non sarà in grado di misurarla correttamente in alcuni casi, perché lo fa non so nulla del genitore. In alcuni casi funzionerà, ma in alcuni non lo farebbe. – Sniper

0

ho trovato un'altra soluzione:

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

Qui i basta avere una dichiarazione if se la vista aveva un genitore e se non ha creato il nuovo dialo g, imposta il contenutoView e mostra la finestra di dialogo nel mio metodo "createAlgorithmDialog()".

Questo imposta anche i pulsanti positivi e negativi (ok e pulsanti Annulla) con onClickListeners.

1

Nel mio caso il problema è stato causato dal fatto che stavo gonfiando la vista padre con il layout <merge>. In questo caso, addView() ha causato l'arresto anomalo.

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

Rimozione addView() ha contribuito a risolvere il problema.

7

semplicemente passare l'argomento attachtoroot come falsa

View view = inflater.inflate(R.layout.child_layout_to_merge, parent_layout, false);