How Parameters Work in LayoutInflater.inflate()

I recently read a lot of references about Android’s LayoutInflater and some of them were difficult to understand. I decided that I was going to write this article and use three simple examples to illustrate different situations of the inflate() method:

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot)
  1. Root is not null, attachToRoot is true
  2. Root is not null, attachToRoot is false
  3. Root is null

First Situation: root is not null, attachToRoot is true

This situation means it’s going to put the layout for the resource at the root, allowing all the root attributes of the resource to work. Here is an example to indicate how it works.

This is what an Activity Layout will look like:

<?xml version=”1.0" encoding=”utf-8"?>
<LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android"
xmlns:tools=”http://schemas.android.com/tools"
android:layout_width=”match_parent”
android:layout_height=”match_parent”
android:orientation=”vertical”
android:id=”@+id/ll”
tools:context=”org.sang.layoutinflater.MainActivity”>
</LinearLayout>

And you will also have a linearLayout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ll"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:orientation="vertical">

If you want to add this linearLayout into your activity’s layout, you can do it like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.linearlayout, ll,true);
}

After, the layout will look like this:

Notice that the view is already there, even though we did not use code to add the image.

If, in this case, I added an additional code line: ll.addView() — it will lead to the crash shown below:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

The reason for this is that it would automatically add the view when we set the attachToRoot to be true.

Second Situation: root is not null, attachToRoot is false

This means it would not add the resource to the root. Some people might be confused here. Why do you need to do this? Why can’t you directly set the root to be null?

To answer this question, we need to know a little bit more about layout_width and layout_height. These two attributes stand for the size of a view in a container, which means the two attributes would only have meaning and perform properly once the view is in the container, if you don’t point a parent layout to it, it would lose the function.

Here, the root is the container and the view is the resource. The key here is we want the root attributes of the linearLayout to work, but at the same time we do not want to add it to the container, we can use this situation to do so.

See this example:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.linearlayout, ll, false);
ll.addView(view);
}

Make note that here, we need to call the addView manually.

Third Situation: root is null

It means we do not need to put the resource to any container, just like the analysis above. In this case, the root attributes would not work properly.

See this example:

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.linearlayout, null, false);
ll.addView(view);
}

You can see the effect below since the height and width for the linearLayout did not work:

What about the inflate method used in Fragment?

If you change the attachToRoot to be true in onCreateView, you would get a crash because when you write the code:

getSupportFragmentManager().beginTransaction()
.replace(R.id.folio_compose_jot_content_frame_id, createJotFragment)
.commit();

Here, you are not responsible for adding childView and only the FragmentManager is responsible. In this case, it will always pass false.

Since you have already added the child fragment in onCreateView(), this is a mistake. Calling add will tell you that child view is already added to parent, hence you will get an IllegalStateException.


As ever, we’re available to help with any software application project — web, mobile, and more! If you are interested in our services you can check out our website. We would love to answer any questions you have! Just reach out to us on our Twitter, Facebook, or LinkedIn.