Advertencia "Evite pasar nulo como raíz de vista" al inflar la vista para que AlertDialog la use

126

Me da la advertencia de pelusa, Avoid passing null as the view rootal inflar con vistas nullcomo parent, por ejemplo:

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

Sin embargo, la vista se debe utilizar como contenido de un AlertDialog, utilizando setViewenAlertDialog.Builder , por lo que no sé qué se debe pasar como parent.

¿Qué crees que parentdebería ser en este caso?

Randy Sugianto 'Yuku'
fuente
2
Pase falso en lugar de nulo. ver esto
MrDumb
Intente darle un diseño principal en lugar de nulo y luego no use setView.
Haresh Chhelana
Suprimo la advertencia de pelusa para el método. Todavía no he visto una buena razón por la que no debería pasar null.
323go
44
Entiendo el problema del diseño dependiendo de la vista principal, pero eso realmente no se aplica a un AlertDialog que esencialmente flota por encima de la jerarquía de vistas de la Actividad. Por eso puedes pasar null. Hay una razón por la que puedes suprimir la pelusa. Se supone que Lint le dará advertencias por problemas que a menudo se pasan por alto; En este caso, es la invocación correcta.
323go
1
@ ashutiwari4 Estoy aprendiendo cosas nuevas todos los días ... mundo hermoso: yo
Rahul

Respuestas:

175

Use este código para inflar la vista de diálogo sin una advertencia:

View.inflate(context, R.layout.dialog_edit, null);
Edward Brey
fuente
77
@ MarianPaździoch Porque no causa una advertencia. :-) Por supuesto, eso plantea la pregunta de por qué las golosinas de código pelusa View.inflatey LayoutInflator.inflatediferente. No he visto una respuesta definitiva. Puede estar relacionado con por qué hay dos formas aparentemente equivalentes de inflar la misma vista, para lo cual tampoco he visto una justificación.
Edward Brey
12
Esto está mal. Solo suprime la advertencia, pero el problema sigue ahí. Lea possiblemobile.com/2013/05/layout-inflation-as-intended para una mejor solución.
jcsahnwaldt Restablece a Monica
16
@JonaChristopherSahnwaldt ¿Podrías dar más detalles? El artículo dice que AlertDialog debería tener un padre nulo porque no tiene una vista raíz. Para mí, parece reforzar que la advertencia tiene sentido para las vistas fuera de un diálogo, pero no es aplicable para una vista de diálogo.
Edward Brey
77
@ EdwardBrey Tienes razón: no leí el artículo a fondo. En este caso particular, está bien usar View.inflate(...null)o @SuppressLint. En general, LayoutInflater.from(...).inflate(..., parent, false)es mejor. ¡Gracias por señalar esto!
jcsahnwaldt Restablece a Monica
1
@Bevor That Evite pasar una pregunta nula es sobre casos en los que tiene un padre. Esta pregunta es sobre AlertDialog, que no proporciona ningún elemento primario para la vista que se está inflando. Al inflar la vista raíz de un AlertDialog, pasar nulo es correcto. Lint no tiene en cuenta este contexto en particular, por lo que la advertencia que da si usa la función que toma parentun falso positivo, no es una indicación de nada propenso a errores. Por eso es válido en este caso usar la función que no toma parenty no dispara ninguna advertencia.
Edward Brey
35

La historia corta es que cuando está inflando una vista para un diálogo, parentdebe ser nulo, ya que no se conoce en el tiempo de inflación de la vista. En este caso, tiene tres soluciones básicas para evitar la advertencia:

  1. Suprima la advertencia con un @Suppress
  2. Inflar la vista usando el método de inflado de la vista . Esto es solo una envoltura alrededor de un LayoutInflater, y sobre todo solo ofusca el problema.
  3. Ver inflar el uso de LayoutInflater método completo : inflate(int resource, ViewGroup root, boolean attachToRoot). Establecer attachToRootenfalse . Esto le dice al inflador que el padre no está disponible. En versiones anteriores de Android Lint, esto eliminaba la advertencia. Este ya no es el caso en las versiones posteriores a la 1.0 de Android Studio.

Visite http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ para una gran discusión sobre este tema, específicamente la sección "Cada regla tiene una excepción" al final.

emerssso
fuente
19

Lanzar nulo como ViewGroup resolvió la advertencia:

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

donde liesta el LayoutInflater'sobjeto

SVL Narasimham
fuente
donde 'li' es el objeto LayoutInflater.
SVL Narasimham
3
Esta respuesta es la mejor, siempre que comprenda POR QUÉ realmente está haciendo esto. La historia corta, como ya habrás leído, es que AlertDialog no conoce a su padre en el momento del inflado, por lo que es un efecto secundario que la pelusa arroja una advertencia en esta situación precisa cuando realmente estás haciendo lo correcto.
Mar Bar
He leído innumerables respuestas y páginas sobre esta advertencia, pero su solución es la mejor con diferencia: simple y elegante
Couitchy
9
Pero es un casting redundante
mohit
11
Luego recibimos otra advertencia "¡El casting es redundante"!
Mousa
17

Deberías usar AlertDialog.Builder.setView(your_layout_id) para no tener que inflarlo.

Utilizar AlertDialog.findViewById(your_view_id) después de crear el diálogo.

Use (AlertDialog) dialogInterfacepara obtener el dialoginterior del OnClickListenery luego dialog.findViewById(your_view_id).

Jeffrey Chen
fuente
1
¡Este es el camino a seguir! Simplemente cree el diálogo y luego encuentre su vista.
user1806772
1
Esta es una buena manera de hacerlo, sin embargo, recuerde que este método se agregó en API 21
Nicolás Carrasco el
¿Qué pasa si debemos almacenar este diseño inflado en alguna variable? Por ejemplo, escribí una clase Aen la que existe el método onCreateDialog. En este último, escribí como dijiste alert_dialog_builder.setView(R.layout.edit_account_dialog);. Pero tengo que almacenar este diseño inflado en la Avariable de atributo llamada the_inflated_layout_of_the_dialog.
JarsOfJam-Scheduler
9

No necesita especificar un parent para un diálogo.

Suprima esto usando @SuppressLint("InflateParams")en la parte superior de la anulación.

kjdion84
fuente
7

Cuando realmente no tiene ninguna parent(por ejemplo, crear vista para AlertDialog), no tiene otra opción que pasar null. Haga esto para evitar advertencias:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);
Mousa
fuente
44
Produce otra advertencia "el valor 'nullParent' siempre es nulo".
mallaudin
A partir de AndroidStudio 3.3 y API 28, esta es la única solución con trabajos.
Zeeshan
1
  1. AlertDialog es, hasta donde yo sé, el único caso en el que puede usar nulo de forma segura lugar de una vista principal. En este caso, puede suprimir la advertencia utilizando:

    @SuppressLint ("InflateParams")

  2. En general, nunca debe usar SupressLint o una de las soluciones mencionadas en las otras respuestas para deshacerse de la advertencia. La vista principal es necesaria para evaluar los parámetros de diseño que se declaran en el elemento raíz de la vista que se está inflando. Eso significa que si usa nulo en lugar de la vista principal, todos los parámetros de diseño en el elemento raíz serán ignorados y reemplazados por parámetros de diseño predeterminados. La mayoría de las veces estará bien, pero en algunos casos resultará en un error realmente difícil de encontrar.

Apfelsaft
fuente
0

De la documentación de View.inflate(), dice

Inflar una vista desde un recurso XML. Este método de conveniencia envuelve la LayoutInflaterclase, que proporciona una gama completa de opciones para ver la inflación.

  @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.
Divya Gupta
fuente
0

De acuerdo con https://developer.android.com/guide/topics/ui/dialogs

Infle y configure el diseño para el diálogo
Pase nulo como la vista principal porque va en el diseño del diálogo

por lo tanto, para crear AlertDialog, uso @SuppressLint("InflateParams")

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

En lugar de hacer

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

hacer

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

Lo inflará con el padre dado, pero no lo adjuntará al padre.

Muchas gracias a Coeffect ( enlace a su publicación )

cristiano
fuente
También sería útil saber cómo conseguir padres.
Johan Karlsson