2014-05-24 15 views
33

Ho un ImageView che allego allo MenuItem come ActionView (l'elemento appare nello ActionBar). Il layout per questa vista proviene da XML. Lo sto gonfiando in questo modo:Cosa devo passare per root quando si gonfia un layout da utilizzare per un ActionView di MenuItem?

ImageView actionView = (ImageView) layoutInflater.inflate(
    R.layout.action_view_layout, null); 

Sembra funzionare correttamente. Però; passando null per root nella chiamata a inflate() rende Lint sgridarmi:

Evitare passando null come radice vista (necessità di risolvere la layout parametri elemento principale del layout di gonfiato)

posso apparentemente gestisco senza una radice nel mio caso specifico, ma preferirei che il codice fosse il più corretto possibile. Il problema è che non sono sicuro di quale View debba essere usato come root qui. This answer dice che dovrebbe essere "il widget che circonda gli oggetti della vista che si desidera gonfiare". Ma cosa significa qui? Quello per la barra delle azioni? L'attività? Qualcos'altro interamente?


Aggiornamento: Leggendo le risposte mi ha fatto la cosa giusta da fare me il sospetto è:

  1. Prendi il ActionBarView corrispondente al MenuItem
  2. Ottenere la sua radice
  3. Gettate la radice a ViewGroup
  4. Passare il risultato al gonfiatore

Questo sembra funzionare. Qualcuno può confermare o negare se questo è ciò che dovrebbe essere fatto?

+7

c'è un eccellente articolo su questo: http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ (ie, per quanto riguarda l'inflazione, non per quanto riguarda la domanda stessa) –

risposta

24

vorrei semplicemente fare in questo modo:

menuItem.setActionView(R.layout.action_view_layout); 

Let Android gonfiare la vista per voi.

Se avete bisogno di fare alcune modifiche in più su questo ImageView chiamata

ImageView imageView = (ImageView) menuItem.getActionView(); 

Aggiornamento

Al fine di soddisfare la vostra curiosità. Questo è ciò che la gente di Google fa sotto il cofano:

public MenuItem setActionView(int resId) { 
    final Context context = mMenu.getContext(); 
    final LayoutInflater inflater = LayoutInflater.from(context); 
    setActionView(inflater.inflate(resId, new LinearLayout(context), false)); 
    return this; 
} 
+0

Beh, geez; Non sapevo nemmeno che esistesse un sovraccarico. Usarlo significa che non posso memorizzare nel cache il risultato dell'inflazione e riutilizzarlo successivamente (spengo e ricollego l'ActionView più volte), ma forse non dovrei farlo comunque. E grazie per aver mostrato cosa fa effettivamente questa funzione; Credo che lo stavo rendendo più complicato del necessario. – dlf

+0

Non penso che sia necessario memorizzarlo nella cache, ma se hai dei duplicati fai un'altra domanda e incolla il link qui, così posso rintracciarlo e darti una risposta. Non dimenticare di pubblicare il tuo codice. Pollice su! –

+0

Non ho assolutamente bisogno * di *; Ho solo pensato di risparmiare il costo di gonfiare il layout ogni volta. Ma è sicuramente un'ottimizzazione prematura. – dlf

3

Generalmente si desidera passare qualsiasi cosa (sottoclasse di ViewGroup) a cui si aggiungerà actionView in per gonfiare. per poter recuperare actionView dalla chiamata di gonfiaggio e non il genitore, ti consigliamo di aggiungere un terzo parametro, falso, in modo che non aggiunga la visualizzazione inflazionata al genitore.

ImageView actionView = 
    (ImageView)layoutInflater.inflate(R.layout.action_view_layout, parent, false); 
// .. do whatever you like with actionView and then add it to it's parent 
menuItem.addActionView(actionView) 

C'è un buon tutorial di here che va in giro le cose un po 'diverso. E 'specificando action_view_layout come parte di menu.xml con qualcosa di simile:

android:actionLayout="@layout/action_view_layout" 

che può anche funzionare per voi, se stai utilizzando sempre lo stesso layout. se si va questa strada si sarebbe in grado di ottenere il ActionView facendo

ImageView actionView = menu.findItem(R.id.whatever).getActionView(); 
11

Hai un'occhiata a questo. spiega bene anche il Layout Inflator.

Ci sono due versioni utilizzabili del metodo inflate() per un'applicazione standard:

inflate(int resource, ViewGroup root) 
inflate(int resource, ViewGroup root, boolean attachToRoot) 

I primi punti dei parametri alla risorsa layout che si desidera per gonfiare.Il secondo parametro è la vista root della gerarchia che si sta gonfiando la risorsa a cui collegarsi. Quando è presente il terzo parametro, determina se la vista gonfiata è collegata o meno alla radice fornita dopo l'inflazione.

Questi ultimi due parametri possono causare un po 'di confusione. Con la versione a due parametri di questo metodo, LayoutInflater tenterà automaticamente di collegare la vista gonfiata alla radice fornita. Tuttavia, il framework ha un controllo sul fatto che se si passa null per la radice si ignora questo tentativo di evitare un arresto anomalo dell'applicazione.

Molti sviluppatori interpretano questo comportamento per indicare che il modo corretto di disattivare l'allegato sull'inflazione è passare null come root; in molti casi non si rende nemmeno conto che esiste la versione a tre parametri di inflate().

More on Layout Inflation

+2

-1 questa risposta semplicemente copia dall'articolo e quindi spiega quale (buona) inflazione è. L'OP presumibilmente lo sa e sta chiedendo un caso speciale a cui questa risposta non aggiunge nulla – avalancha