Avviso "Evita di passare null come radice della vista" quando si gonfia la vista per l'utilizzo da parte di AlertDialog


126

Ricevo l'avvertimento di lanugine Avoid passing null as the view rootquando gonfio le viste con nullas parent, come:

LayoutInflater.from(context).inflate(R.layout.dialog_edit, null);

Tuttavia, la vista deve essere utilizzata come contenuto di un AlertDialog, usando setViewon AlertDialog.Builder, quindi non so cosa dovrebbe essere passato come parent.

Cosa pensi che parentdovrebbe essere in questo caso?


2
Passa false anziché null. vedi questo
MrDumb

Prova a darti il ​​layout genitore invece di null e quindi non utilizzare setView.
Haresh Chhelana,

Sopprimo l'avvertimento del filaccia per il metodo. Non ho ancora visto un buon motivo per cui non dovrei passare null.
323go

4
Capisco il problema del layout a seconda della vista principale, ma ciò non si applica in realtà ad un AlertDialog che galleggia essenzialmente al di sopra della gerarchia della vista dell'Attività. Ecco perché puoi passare null. C'è una ragione per cui puoi eliminare la lanugine. Lint dovrebbe darti avvertimenti per problemi spesso persi; in questo caso, è invocazione corretta.
323go

1
@ ashutiwari4 Sto imparando cose nuove ogni giorno .. bellissimo mondo: I
Rahul

Risposte:


175

Utilizzare questo codice per gonfiare la vista della finestra di dialogo senza un avviso:

View.inflate(context, R.layout.dialog_edit, null);

7
@ MarianPaździoch Perché non provoca un avviso. :-) Certo, questo pone la domanda sul perché il codice lanugine tratta View.inflatee in modo LayoutInflator.inflatediverso. Non ho visto una risposta definitiva. Potrebbe essere collegato al perché ci sono due modi apparentemente equivalenti per gonfiare la stessa visione, per i quali non ho visto nemmeno una logica.
Edward Brey,

12
Questo è sbagliato. Elimina solo l'avviso, ma il problema è ancora presente. Leggi possibilemobile.com/2013/05/layout-inflation-as-intended per una soluzione migliore.
jcsahnwaldt Reinstate Monica,

16
@JonaChristopherSahnwaldt Potresti elaborare? L'articolo dice che AlertDialog dovrebbe avere un genitore nullo perché non ha una vista radice. A me sembra rinforzare che l'avvertimento ha senso per le viste al di fuori di una finestra di dialogo ma non è applicabile per una vista di dialogo.
Edward Brey,

7
@EdwardBrey Hai ragione: non ho letto l'articolo a fondo. In questo caso particolare, è OK usare View.inflate(...null)o @SuppressLint. In generale, LayoutInflater.from(...).inflate(..., parent, false)è meglio. Grazie per averlo segnalato!
jcsahnwaldt Reinstate Monica,

1
@Bevor che evitare di passare una domanda nulla riguarda i casi in cui hai un genitore. Questa domanda è circa AlertDialog, che non fornisce alcun genitore per la vista da gonfiare. Quando si gonfia la vista radice di un AlertDialogpassaggio null è corretto. Lint non tiene conto di questo particolare contesto, quindi l'avvertimento che dà se si utilizza la funzione che assume parentun falso positivo, non un'indicazione di errori soggetti a errori. Ecco perché in questo caso è valido utilizzare la funzione che non accetta parente non attiva alcun avviso.
Edward Brey,

35

La storia breve è che quando si gonfia una vista per una finestra di dialogo, parentdovrebbe essere nulla, poiché non è noto in Visualizza tempo di gonfiaggio. In questo caso, hai tre soluzioni di base per evitare l'avvertimento:

  1. Sopprimere l'avviso utilizzando un @Suppress
  2. Gonfia la vista usando il metodo di gonfiaggio della vista . Questo è solo un involucro attorno a LayoutInflater e per lo più offusca il problema.
  3. Gonfiare la vista utilizzando del LayoutInflater metodo integrale : inflate(int resource, ViewGroup root, boolean attachToRoot). Imposta attachToRootsu false. Questo indica al gonfiatore che il genitore non è disponibile. Nelle versioni precedenti di Android Lint, questo ha rimosso l'avviso. Questo non è più il caso nelle versioni post 1.0 di Android Studio.

Controlla http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ per una grande discussione su questo problema, in particolare la sezione "Ogni regola ha un'eccezione" alla fine.


19

Il cast di null come ViewGroup ha risolto l'avviso:

View dialogView = li.inflate(R.layout.input_layout,(ViewGroup)null);

dov'è lil' LayoutInflater'soggetto.


dove 'li' è l'oggetto LayoutInflater.
SVL Narasimham,

3
Questa risposta è la migliore, a condizione che tu capisca PERCHÉ lo stai effettivamente facendo. Per farla breve, come avrete già letto, AlertDialog non conosce il suo genitore al momento del gonfiaggio, e quindi è un effetto collaterale che lint lancia un avvertimento in questa precisa situazione quando state effettivamente facendo la cosa giusta.
Mar Bar,

Ho letto innumerevoli risposte e pagine su questo avvertimento, ma la tua soluzione è di gran lunga la migliore: semplice ed elegante
Couitchy

9
Ma è un casting ridondante
mohit,

11
Quindi riceviamo un altro avviso "Casting ridondante"!
Mousa,

17

Dovresti usare AlertDialog.Builder.setView(your_layout_id) , quindi non è necessario gonfiarlo.

Uso AlertDialog.findViewById(your_view_id) dopo aver creato la finestra di dialogo.

Utilizzare (AlertDialog) dialogInterfaceper ottenere l' dialoginterno OnClickListenere quindi dialog.findViewById(your_view_id).


1
Questa è la strada da percorrere! Basta creare la finestra di dialogo e quindi trovare la vista.
user1806772

1
Questo è un buon modo per farlo, tuttavia ricorda che questo metodo è stato aggiunto in API 21
Nicolás Carrasco

E se dovessimo memorizzare questo layout gonfiato in qualche variabile? Ad esempio, ho scritto una classe Ain cui esiste il metodo onCreateDialog. In quest'ultimo, ho scritto come hai detto alert_dialog_builder.setView(R.layout.edit_account_dialog);. Ma devo memorizzare questo layout gonfiato nella Avariabile dell'attributo denominata the_inflated_layout_of_the_dialog.
JarsOfJam-Scheduler,

9

Non è necessario specificare a parentper una finestra di dialogo.

Sopprimilo usando @SuppressLint("InflateParams")nella parte superiore della sostituzione.


7

Quando davvero non ne hai parent(per esempio creare una vista per AlertDialog), non hai altra scelta che passare null. Quindi, fai questo per evitare avvertimenti:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);

4
Produce un altro avviso "il valore 'nullParent' è sempre null."
Mallaudin,

A partire da AndroidStudio 3.3 e API 28, questa è l'unica soluzione con opere.
Zeeshan,

1
  1. L'AlertDialog è per quanto ne so l'unico caso in cui puoi tranquillamente usare null anziché una vista padre. In questo caso è possibile sopprimere l'avviso utilizzando:

    @SuppressLint ( "InflateParams")

  2. In generale non si dovrebbe mai usare SupressLint o una delle soluzioni alternative menzionate nelle altre risposte per eliminare l'avviso. La vista padre è necessaria per valutare i Param di layout che sono dichiarati nell'elemento radice della Vista da gonfiare. Ciò significa che se si utilizza null anziché la vista principale, tutti i parametri di layout nell'elemento radice verranno ignorati e sostituiti dai parametri di layout predefiniti. Il più delle volte andrà bene, ma in alcuni casi si tradurrà in un bug davvero difficile da trovare.


0

Dalla documentazione di View.inflate(), dice

Gonfiare una vista da una risorsa XML. Questo metodo conveniente avvolge la LayoutInflaterclasse, che offre una gamma completa di opzioni per visualizzare l'inflazione.

  @param context The Context object for your activity or application.
  @param resource The resource ID to inflate
  @param root A view group that will be the parent.  Used to properly inflate the  layout_* parameters.

0

Secondo https://developer.android.com/guide/topics/ui/dialogs

Gonfia e imposta il layout per la finestra di dialogo
Passa null come vista padre perché va nel layout della finestra di dialogo

pertanto, per creare AlertDialog, utilizzo @SuppressLint("InflateParams")

LayoutInflater inflater = requireActivity().getLayoutInflater();
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view);

-1

Invece di farlo

view = inflater.inflate(R.layout.list_item, null);

fare

view = inflater.inflate(R.layout.list_item, parent, false);

Lo gonferà con il genitore specificato, ma non lo collegherà al genitore.

Mille grazie a Coeffect ( link al suo post )


Sarebbe anche utile sapere come diventare genitore.
Johan Karlsson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.