Aviso "Evite passar nulo como raiz da exibição" ao inflar a exibição para uso pelo AlertDialog

126

Recebo o aviso de fiapo, Avoid passing null as the view rootao inflar visualizações com nullas parent, como:

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

No entanto, a visualização deve ser usada como o conteúdo de um AlertDialog, usando setViewon AlertDialog.Builder, então não sei o que deve ser passado como parent.

O que você acha que parentdeveria ser nesse caso?

Randy Sugianto 'Yuku'
fonte
2
Passe falso em vez de nulo. veja isso
MrDumb 16/10
Tente fornecer o layout pai em vez de nulo e não use o setView.
Haresh Chhelana
Eu suprimo o aviso de fiapos para o método. Ainda não vi uma boa razão para não passar null.
323go #
4
Entendo o problema de layout, dependendo da exibição pai, mas isso não se aplica a um AlertDialog que basicamente flutua acima da hierarquia de exibição da Atividade. É por isso que você pode passar null. Há uma razão para você suprimir o fiapo. Supõe-se que o Lint avise sobre problemas perdidos com frequência; neste caso, é invocação correta.
323go 17/10/2014
1
@ ashutiwari4 Estou aprendendo novas coisas novas todos os dias .. belo mundo: I
Rahul

Respostas:

174

Use este código para aumentar a exibição da caixa de diálogo sem aviso:

View.inflate(context, R.layout.dialog_edit, null);
Edward Brey
fonte
7
@ MarianPaździoch Porque não causa um aviso. :-) Obviamente, isso levanta a questão de por que o código do lint trata View.inflatee de maneira LayoutInflator.inflatediferente. Eu não vi uma resposta definitiva. Pode estar relacionado ao motivo pelo qual existem duas maneiras aparentemente equivalentes de inflar a mesma visão, para as quais também não vi uma justificativa.
Edward Brey
12
Isto está errado. Ele apenas suprime o aviso, mas o problema ainda está lá. Leia possiblemobile.com/2013/05/layout-inflation-as-intended para uma solução melhor.
Jcsahnwaldt Restabelecer Monica
16
@JonaChristopherSahnwaldt Você poderia elaborar? O artigo diz que AlertDialog deve ter um pai nulo porque não tem uma exibição raiz. Para mim, parece reforçar que o aviso faz sentido para exibições fora de uma caixa de diálogo, mas não é aplicável a uma exibição de caixa de diálogo.
Edward Brey
7
@ EdwardBrey Você está certo - eu não li o artigo completamente. Nesse caso em particular, não há problema em usar um View.inflate(...null)ou outro @SuppressLint. Em geral, LayoutInflater.from(...).inflate(..., parent, false)é melhor. Obrigado por apontar isso!
Jcsahnwaldt Restabelecer Monica
1
@ Bevor That Evitar passar perguntas nulas é sobre casos em que você tem um pai. Esta questão é sobre AlertDialog, que não fornece pai para a exibição que está sendo inflada. Ao inflar a visualização raiz de um AlertDialog, passar nulo está correto. O Lint não é responsável por esse contexto específico; portanto, o aviso emitido se você usar a função que recebe parentum falso positivo, não é uma indicação de algo propenso a erros. É por isso que é válido, neste caso, usar a função que não aceita parente aciona nenhum aviso.
Edward Brey
35

A história resumida é que, quando você está inflando uma visualização para um diálogo, parentdeve ser nulo, pois não é conhecido no momento da inflação da Visualização. Nesse caso, você tem três soluções básicas para evitar o aviso:

  1. Suprimir o aviso usando um @Suppress
  2. Inflar o modo de exibição usando o método de inflar do modo de exibição . Este é apenas um invólucro em torno de um LayoutInflater e, na maioria das vezes, ofusca o problema.
  3. Inflar o View usando de LayoutInflater método integral : inflate(int resource, ViewGroup root, boolean attachToRoot). Defina attachToRootcomo false. Isso informa ao inflador que o pai não está disponível. Nas versões mais antigas do Android Lint, isso removeu o aviso. Esse não é mais o caso das versões posteriores ao 1.0 do Android Studio.

Confira http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ para uma ótima discussão sobre esse problema, especificamente a seção "Toda regra tem uma exceção" no final.

emerssso
fonte
19

A conversão de nulo como ViewGroup resolveu o aviso:

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

onde liestá o LayoutInflater'sobjeto

SVL Narasimham
fonte
onde 'li' é o objeto LayoutInflater.
SVL Narasimham
3
Esta resposta é a melhor, desde que você entenda por que está realmente fazendo isso. A história curta, como você já deve ter lido, é que o AlertDialog não conhece seu pai no momento da inflação e, portanto, é um efeito colateral que o fiapo lança um aviso nessa situação precisa quando você realmente está fazendo a coisa certa.
Mar Bar
Eu li inúmeras respostas e páginas sobre este aviso, mas sua solução é o melhor de longe: simples e elegante
Couitchy
9
Mas é redundante fundição
mohit
11
Depois, recebemos outro aviso "A transmissão é redundante"!
M
17

Você deve usar AlertDialog.Builder.setView(your_layout_id), para não precisar inflar.

Use AlertDialog.findViewById(your_view_id)depois de criar a caixa de diálogo.

Use (AlertDialog) dialogInterfacepara obter o dialoginterior do OnClickListenere então dialog.findViewById(your_view_id).

Jeffrey Chen
fonte
1
Este é o caminho a seguir! Basta criar a caixa de diálogo e depois encontrar sua visão.
user1806772
1
Esta é uma boa maneira de fazê-lo, no entanto lembre-se que este método foi adicionado na API 21
Nicolás Carrasco
E se precisarmos armazenar esse layout inflado em alguma variável? Por exemplo, eu escrevi uma classe Aem que há o método onCreateDialog. Neste último, escrevi como você disse alert_dialog_builder.setView(R.layout.edit_account_dialog);. Mas eu tenho que armazenar esse layout inflado na Avariável de atributo do nome the_inflated_layout_of_the_dialog.
JarsOfJam-Scheduler
9

Você não precisa especificar um parentpara um diálogo.

Suprima isso usando @SuppressLint("InflateParams")na parte superior da substituição.

kjdion84
fonte
7

Quando você realmente não tem nenhuma parent(por exemplo, criando view para AlertDialog), não tem outra opção senão a aprovação null. Faça isso para evitar aviso:

final ViewGroup nullParent = null;
convertView = infalInflater.inflate(R.layout.list_item, nullParent);
Mousa
fonte
4
Ele produz outro aviso "o valor 'nullParent' é sempre nulo".
mallaudin
A partir do AndroidStudio 3.3 e API 28, esta é a única solução que funciona.
Zeeshan #
1
  1. O AlertDialog é, até onde eu sei, o único caso em que você pode usar com segurança nulo vez de uma exibição pai. Nesse caso, você pode suprimir o aviso usando:

    @SuppressLint ("InflateParams")

  2. Em geral, você nunca deve usar o SupressLint ou uma das soluções alternativas mencionadas nas outras respostas para se livrar do aviso. A visualização pai é necessária para avaliar os Parâmetros de Layout declarados no elemento raiz da Visualização que está sendo inflada. Isso significa que, se você usar nulo em vez da exibição pai, todos os Parâmetros de Layout no elemento raiz serão ignorados e substituídos pelos Parâmetros de Layout padrão. Na maioria das vezes, tudo fica bem, mas em alguns casos isso resulta em um bug realmente difícil de encontrar.

Apfelsaft
fonte
0

Da documentação de View.inflate(), diz

Infle uma exibição de um recurso XML. Esse método de conveniência envolve a LayoutInflaterclasse, que fornece uma gama completa de opções para visualizar a inflação.

  @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
fonte
0

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

Inflar e definir o layout da caixa de diálogo
Pass null como a visualização principal, porque está sendo exibida no layout da caixa de diálogo

portanto, para criar AlertDialog, eu uso @SuppressLint("InflateParams")

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

Em vez de fazer

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

Faz

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

Ele irá inflá-lo com o pai fornecido, mas não o anexará ao pai.

Muito obrigado a Coeffect ( link para seu post )

cristão
fonte
Também seria útil saber como obter os pais.
Johan Karlsson