2011-06-22 14 views
30

Ho un LinearLayout con orientamento verticale come genitore, voglio aggiungere qualche vista programmaticamente più volte a questo genitore. In questo momento sto gonfiando il bambino ogni volta ricevendo nuovi riferimenti a ogni elemento dell'interfaccia utente prima di aggiungerlo al genitore. Questo non sembra essere molto efficiente, c'è un modo migliore per farlo.Come aggiungere la stessa vista al genitore più volte gonfiandolo solo una volta

Il codice corrente che sto usando è sotto, Se mi infilo solo una volta prima per ciclo ottengo errore di runtime "ha specificato che il figlio ha già un genitore. Devi chiamare removeView() sul genitore del figlio prima."

 LayoutInflater inflator = LayoutInflater.from(getBaseContext()); 
     LinearLayout parentPanel = findViewById(R.id.parent_pannel); 

     ArrayList<String> myList = getData(); 
     for(String data : myList) { 
      // inflate child 
      View item = inflator.inflate(R.layout.list_item, null); 
      // initialize review UI 
      TextView dataText = (TextView) item.findViewById(R.id.data); 
      // set data 
      dataText.setText(data); 
      // add child 
      parentPanel.addView(item); 
     } 
+0

Sono d'accordo, sarebbe bello se ci fosse un modo semplice per "clonare" le visualizzazioni, ma devo ancora trovarlo. Gonfiando all'infinito è. Tuttavia, devo dire che dal tuo frammento di codice, sembrerebbe che tu voglia usare un 'ListView'. – dmon

+0

Ho paura che questo sia di progettazione. Non puoi avere più genitori per una vista, oltre ad aggiungere la stessa vista al genitore più volte. Sarebbe abbastanza difficile scrivere codice senza bug per ViewGroups (e scenari simili) se non fosse così. – inazaruk

+0

@dmon Non ho progettato il mio layout per usare ListView perché avrebbe reso il codice più complesso perché volevo che ogni cosa venisse disposta. Credo che per l'efficienza devo spostare tutto su ListView. – mkso

risposta

4

non sono sicuro di che cosa il vostro punto di vista è, ma hai crearlo manualmente sopra gonfiare il XML:

ArrayList<String> myList = getData(); 
    for(String data : myList) { 

     LinearLayout layout = new LinearLayout(this); 
     layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,    LayoutParams.WRAP_CONTENT)); 
     TextView textView = new TextView(this); 
     textView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 

     textView.setText(data); 

     layout.addChild(textView);   

     parentPanel.addView(layout); 
    } 

Ma sì il tuo qualcosa di chiaramente il tentativo che è stato fatto per voi con Simple ListView & API

28

Avete effettivamente controllato se il gonfiaggio è lento? Per quanto ne so, la visualizzazione di gonfiaggio è molto veloce (quasi veloce come creare manualmente le visualizzazioni).

Potrebbe essere sorprendente per te sentire ma gonfiare in effetti non analizza affatto gli XML. Gli XML per il layout sono analizzati e preelaborati in fase di compilazione - sono archiviati in un formato binario che rende molto efficiente l'inflazione della vista (ecco perché non è possibile gonfiare una vista da un XML generato in fase di runtime).

+1

interessante! – Blundell

+3

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/view/LayoutInflater.java riga 424 – Teodor

+0

Non sono d'accordo su questo, durante le mie creazioni di attività o frammenti, l'inflazione XML è sempre ciò che richiede il tempo più lungo, ecco perché cerco di mantenere la struttura del layout il più semplice possibile. –

4

Il gonfiaggio di più volte non può essere eseguito allo stesso modo eseguendolo in scatto singolo. Spero che questo funziona

LayoutInflater inflator = (LayoutInflater).getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    LinearLayout parentPanel = findViewById(R.id.parent_pannel); 

    ArrayList<String> myList = getData(); 
    for(String data : myList) { 
     // inflate child 
     View item = inflator.inflate(R.layout.list_item, null); 
     // initialize review UI 
     TextView dataText = (TextView) item.findViewById(R.id.data); 
     // set data 
     dataText.setText(data); 
     // add child 
     parentPanel.addView(item); 
    } 

Questo lavoro, per lo meno mi ha lavorato

+0

Ha funzionato anche per me con View v = inflater.inflate (R.layout.list_item, parent, false) seguito in seguito chiamando addView (v). Sembra che la gonfiatura (...) possa avere un'ottimizzazione da non attaccare se è già presente. –

+0

mi puoi suggerire qualcosa se devo aggiungere dinamicamente la vista come sopra all'interno di una riga di vista del riciclatore –

5

Non è possibile, anche se si tenta di creare un new view dal vecchio view oggetto l'oggetto verrà passato per riferimento non valore, e quindi avrai un'EEccezione come childAlreadyHasParent, e così, l'unico modo è di mettere il view in un for loop con il numero di volte che vuoi che venga gonfiato, e questo ciclo deve contenere il processo di creazione da beginni ng non solo le linee di gonfiaggio.

Problemi correlati