142

I get the lint warning, Avoid passing null as the view root when inflating views with null as parent, like:

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

However, the view is to be used as the content of an AlertDialog, using setView on AlertDialog.Builder, so I don't know what should be passed as the parent.

What do you think the parent should be in this case?

Randy Sugianto 'Yuku'
  • 71,383
  • 57
  • 178
  • 228
  • 3
    Pass false instead of null. see [this](http://stackoverflow.com/questions/24832497/avoid-passing-null-as-the-view-root-need-to-resolve-layout-parameters-on-the-in) – MrDumb Oct 16 '14 at 12:54
  • Try to given you parent layout instead of null and then don't use setView. – Haresh Chhelana Oct 16 '14 at 13:09
  • I suppress the lint warning for the method. I have not yet seen a good reason why I shouldn't pass `null`. – 323go Oct 16 '14 at 14:09
  • @323go it's a valid warning when the parent is known, because the type of LayoutParams that the view will get depends on the parent. But there should be some reason the lint developer enables this warning for every inflate call. – Randy Sugianto 'Yuku' Oct 16 '14 at 16:49
  • 4
    I understand the layout issue depending on the parent view, but that doesn't really apply for an AlertDialog which essentially floats above the Activity's view hierarchy. That is why you can pass `null`. There's a reason that you can suppress lint. Lint is supposed to give you warnings for often-missed issues; in this case, it's correct invocation. – 323go Oct 17 '14 at 01:50
  • For those looking, to do this the exact suppression needed is `@SuppressLint("InflateParams")`. – carthurs Jan 28 '17 at 13:38
  • 1
    @ashutiwari4 I am learning new new things everyday.. beautiful world :I – Rahul Apr 24 '17 at 06:51

11 Answers11

192

Use this code to inflate the dialog view without a warning:

View.inflate(context, R.layout.dialog_edit, null);
Edward Brey
  • 40,302
  • 20
  • 199
  • 253
  • 9
    @MarianPaździoch Because it doesn't cause a warning. :-) Of course, that begs the question of why the lint code treats `View.inflate` and `LayoutInflator.inflate` differently. I've not seen a definitive answer. It may be related to why there are two seemingly equivalent ways to inflate the same view, for which I've also not seen a rationale. – Edward Brey Feb 09 '15 at 13:37
  • 13
    This is wrong. It only suppresses the warning, but the problem is still there. Read http://possiblemobile.com/2013/05/layout-inflation-as-intended/ for a better solution. – jcsahnwaldt Reinstate Monica May 18 '15 at 15:40
  • 17
    @JonaChristopherSahnwaldt Could you elaborate? The article says that AlertDialog should have a null parent because it does not have a root view. To me it seems to reinforce that the warning makes sense for views outside a dialog but is not applicable for a dialog view. – Edward Brey May 18 '15 at 15:46
  • 10
    @EdwardBrey You are right - I didn't read the article thoroughly. In this particular case, it's OK to use either ```View.inflate(...null)``` or ```@SuppressLint```. In general, ```LayoutInflater.from(...).inflate(..., parent, false)``` is better. Thanks for pointing this out! – jcsahnwaldt Reinstate Monica May 18 '15 at 15:54
  • 1
    How it's OK to `@SuppressLint`? Suppress means warning is still there but you are choosing for it to not disturb you. – Bugs Happen Aug 23 '15 at 17:53
  • @BugsHappen Normally, you would suppress a lint warning to indicate that it is not applicable in a given context. With the static `inflate` method, however, there is no lint warning to begin with. – Edward Brey Aug 23 '15 at 18:48
  • The problem in this solution is if you are using that in onCreateView for example you already have LayoutInflater so with this method you will create another one for what ? avoiding @SuppressLint ? – Jesus Dimrix Oct 09 '16 at 12:56
  • @JesusDimrix I wonder if by avoiding the code for suppression and getting the activity's inflater, you'd get a speedup for download and load time that results in a better overall user experience than avoiding the cost of creating the extra inflater object. Both differences seem like they'd be imperceptibly small. – Edward Brey Nov 28 '16 at 21:08
  • 1
    -1 Although this answers the question, it's bad to suggest a solution that just bypasses the Lint check (and is technically error prone). The correct answer should be the one from here: https://stackoverflow.com/questions/24832497/avoid-passing-null-as-the-view-root-need-to-resolve-layout-parameters-on-the-in – Bevor Dec 08 '18 at 10:58
  • 3
    @Bevor That [Avoid passing null](https://stackoverflow.com/a/24832569/145173) question is about cases where you have a parent. This question is about `AlertDialog`, which provides no parent for the view being inflated. When inflating the root view of an `AlertDialog`, passing null is correct. Lint doesn't account for this particular context, so the warning it gives if you use the function that takes `parent` a false positive, not an indication of anything error prone. That's why it's valid in this case to use the function that takes no `parent` and triggers no warning. – Edward Brey Dec 08 '18 at 13:01
  • Ummm, then sorry. I didn't consider that. – Bevor Dec 08 '18 at 17:58
38

The short story is that when you are inflating a view for a dialog, parent should be null, since it is not known at View inflation time. In this case, you have three basic solutions to avoid the warning:

  1. Suppress the warning using an @Suppress
  2. Inflate the View using View's inflate method. This is just a wrapper around a LayoutInflater, and mostly just obfuscates the problem.
  3. Inflate the View using LayoutInflater's full method: inflate(int resource, ViewGroup root, boolean attachToRoot). Set attachToRoot to false.This tells the inflater that the parent is not available. In older versions of Android Lint, this removed the warning. This is no longer the case in post 1.0 versions of Android Studio.

Check out http://www.doubleencore.com/2013/05/layout-inflation-as-intended/ for a great discussion of this issue, specifically the "Every Rule Has an Exception" section at the end.

emerssso
  • 2,376
  • 18
  • 24
22

You should use AlertDialog.Builder.setView(your_layout_id), so you don't need to inflate it.

Use AlertDialog.findViewById(your_view_id) after creating the dialog.

Use (AlertDialog) dialogInterface to get the dialog inside the OnClickListener and then dialog.findViewById(your_view_id).

Jeffrey Chen
  • 1,777
  • 1
  • 18
  • 29
  • 1
    This is the way to go! Just create the dialog and then find your view. – joe1806772 Mar 28 '17 at 23:02
  • 1
    This is a good way to do it, however remember that this [method](https://developer.android.com/reference/android/app/AlertDialog.Builder.html#setView(int)) was added in API 21 – Nicolás Carrasco-Stevenson Apr 11 '18 at 07:07
  • What if we must store this inflated layout in some variable? For example, I wrote a class `A` in which there is the method `onCreateDialog`. In the latter, I wrote as ou said `alert_dialog_builder.setView(R.layout.edit_account_dialog);`. But I have to store this inflated layout in the `A`'s attribute variable named `the_inflated_layout_of_the_dialog`. – JarsOfJam-Scheduler Feb 26 '19 at 21:56
18

Casting null as ViewGroup resolved the warning:

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

where li is the LayoutInflater's object.

Kaushik
  • 6,150
  • 5
  • 39
  • 54
SVL Narasimham
  • 213
  • 2
  • 2
  • where 'li' is the LayoutInflater object. – SVL Narasimham Nov 03 '15 at 21:33
  • 3
    This answer is the best, providing you understand WHY you are actually doing this. Short story, as you might have already read, is that AlertDialog does not know its parent at inflate time, and so it's a side effect that lint throws a warning in this precise situation when you actually are doing the right thing. – Mar Bar Nov 13 '15 at 15:39
  • I've read countless answers and pages about this warning, but your solution is the best by far: simple and elegant – Couitchy Mar 21 '16 at 15:02
  • 9
    But it is redundant casting – mohit Apr 15 '16 at 09:58
  • 12
    Then we get another warning "Casting is redundant"! – Mousa Jun 11 '16 at 08:50
  • 1
    are you joking? – user25 Jul 06 '18 at 18:37
  • @mohit and Mousa , you can suppress redundant casting warning by write this exactly before the method declaration: @SuppressWarnings("RedundantCast") – Dika Jul 26 '18 at 04:49
9

You don't need to specify a parent for a dialog.

Suppress this using @SuppressLint("InflateParams") at the top of the override.

kjdion84
  • 9,552
  • 8
  • 60
  • 87
8

Edit:

At the time of writing this answer, I was not aware of Lint suppressions. It's better to suppress Lint instead of tricking the IDE. Add this above the line or method:

@SuppressLint("InflateParams")

Old answer:

When you really don't have any parent (for example creating view for AlertDialog), you have no other choice than passing null. So do this to avoid warning:

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

// Kotlin
val nullParent: ViewGroup? = null
val convertView = layoutInflater.inflate(R.layout.my_dialog, nullParent)
Mousa
  • 2,190
  • 3
  • 21
  • 34
1

According to https://developer.android.com/guide/topics/ui/dialogs

Inflate and set the layout for the dialog
Pass null as the parent view because its going in the dialog layout

therefore, for creating AlertDialog, I use @SuppressLint("InflateParams")

LayoutInflater inflater = requireActivity().getLayoutInflater();
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.layout_dialog, null);
builder.setView(view);
Dharman
  • 30,962
  • 25
  • 85
  • 135
Cor
  • 389
  • 1
  • 2
  • 14
0
  1. The AlertDialog is as far as I know the only case were you can safely use null instead of a parent view. In this case you can suppress the warning by using:

    @SuppressLint("InflateParams")

  2. In general you should never use SupressLint or one of the workarounds mentioned in the other answers to get rid of the warning. The parent view is necessary to evaluate the Layout Params which are declared in the root element of the View being inflated. That means if you use null instead of the parent view, all Layout Params in the root element will be ignored and replaced by default Layout Params. Most of the time it will be fine, but in some cases it will result in a really hard-to-find bug.

Apfelsaft
  • 5,766
  • 4
  • 28
  • 37
0

Android's docs (AlertDialog) says:

If you want to display a more complex view, look up the FrameLayout called "custom" and add your view to it:

FrameLayout fl = findViewById(android.R.id.custom);
fl.addView(myView, new LayoutParams(MATCH_PARENT, WRAP_CONTENT));

Therefore, we can use fl as parent in our case:

FrameLayout fl = findViewById(android.R.id.custom);
View view = LayoutInflater.from(context).inflate(R.layout.custom_dialog, fl, false);

It works, but I'm not sure that it's efficient or not

Amit
  • 53
  • 4
-1

From the documentation of View.inflate(), it says

Inflate a view from an XML resource. This convenience method wraps the LayoutInflater class, which provides a full range of options for view inflation.

  @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
  • 494
  • 8
  • 24
-2

Instead of doing

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

do

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

It will inflate it with the given parent, but won't attach it to the parent.

Many thanks to Coeffect (link to his post)

Community
  • 1
  • 1
Christian
  • 748
  • 7
  • 23