Skip to content

Instantly share code, notes, and snippets.

@pokk
Last active January 13, 2017 07:44
Show Gist options
  • Save pokk/5f2c73f90f1b38fb4f96cf6dd45680af to your computer and use it in GitHub Desktop.
Save pokk/5f2c73f90f1b38fb4f96cf6dd45680af to your computer and use it in GitHub Desktop.

Inflater

This method LayoutInflater.inflate is used all the time and useful if you are developing the related of views or animations. I think a junior Android programmer isn't often using it but I believe definitely that a senior engineer use this method every day.

Let's go to main topic. When we create a activity or a fragment or a view, we may add some sub-view into. But sometime succeed, sometimes failed.

problem

We have a (A) base xml layout of an activity here.

<RelativeLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/tv_show"/>
    <LinearLayout
        android:id="@+id/container"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp">
    </LinearLayout>

</RelativeLayout>

We wanna add this B layout(FrameLayout) to C layout(LinearLayout) of A base layout.

<FrameLayout android:id="@+id/ll_test"
             xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="250dp"
             android:layout_height="100dp"
             android:background="@color/colorPrimaryDark"
             android:orientation="vertical">
    <Button
        android:layout_marginTop="30dp"
        android:id="@+id/btn_test"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:text="Button"/>
    <TextView
        android:id="@+id/tv_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"/>
</FrameLayout>

We set this B layout(FrameLayout)'s width and height are 250dp and 100dp. Then we can use inflate method to add B layout(FrameLayout) into C layout(LinearLayout).

LinearLayout layout = (LinearLayout)findViewById(R.id.container);
View view = View.inflate(this, R.layout.layout_menu_item, null);
layout.addView(view);

Then we can figure out that B layout's setting wasn't set correctly. In other words, the setting wasn't executed. This inflate method ignored me :((

How to set correctly

First, I'd like to introduce and share inflate method to you.

Everybody knows inflate method is that show a view to the screen, but there are some ways we can use.

Method 1:

View v = View.inflate(this, R.layout.layout_your, root);
View v = getLayoutInflater().inflate(this, R.layout.layout_your, root);

Method 2:

View v = LayoutInflater.from(context).inflate(R.layout.layout_your, root);

Method 3:

View v = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).inflate(R.layout.layout_your, root);

Actually the above of them are totally same things. If you dig deeper into the View.inflate, you can find out that LayoutInflater.from(context) is called inside View.inflate. And you dig into again LayoutInflater.from, you can see that (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) is called by LayoutInflater.from.

Briefly speaking, all of them are equal.

Summary

After I dug deeper into the SDK source code. I directly say brief summary.

There are three parameters of 'inflate(int resource, ViewGroup root, boolean attachToRoot)' method as below.

  1. resource: A layout id of a xml, ex: B layout(FrameLayout).
  2. root: This is a nullable parameter. ex: C root layout(LinearLayout).
  3. attachToRoot: Generate view add into root layout. ex: B layout(FrameLayout) add to C root layout(LinearLayout).

Here I will tell you directly about the parameters what we input then what kind of the view will show.

  1. If root == null, attachToRoot will be ineffective, then the parameter layout's setting won't be set. Return the parameter layout.
  2. If root != null AND attachToRoot == true, the parameter layout will be generated. Return the parameter layout.
  3. If root != null AND attachToRoot == false, the parameter layout will be generated and be set and add to the root automatically. Return the root layout.
  4. If don't set attachToRoot, attachToRoot != root as a parameter will be set automatically.

So if return value is that parameter layout(B layout), you need to call layout.addView(view); by yourself.

Better way to use

View view = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, false);
layout.addView(view);

Inflater

This method LayoutInflater.inflate is used all the time and useful if you are developing the related of views or animations. I think a junior Android programmer isn't often using it but I believe definitely that a senior engineer use this method every day.

Let's go to main topic. When we create a activity or a fragment or a view, we may add some sub-view into. But sometime succeed, sometimes failed.

problem

We have a (A) base xml layout of an activity here.

<RelativeLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/tv_show"/>
    <LinearLayout
        android:id="@+id/container"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="50dp">
    </LinearLayout>

</RelativeLayout>

We wanna add this B layout(FrameLayout) to C layout(LinearLayout) of A base layout.

<FrameLayout android:id="@+id/ll_test"
             xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="250dp"
             android:layout_height="100dp"
             android:background="@color/colorPrimaryDark"
             android:orientation="vertical">
    <Button
        android:layout_marginTop="30dp"
        android:id="@+id/btn_test"
        android:layout_width="200dp"
        android:layout_height="50dp"
        android:text="Button"/>
    <TextView
        android:id="@+id/tv_test"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"/>
</FrameLayout>

We set this B layout(FrameLayout)'s width and height are 250dp and 100dp. Then we can use inflate method to add B layout(FrameLayout) into C layout(LinearLayout).

LinearLayout layout = (LinearLayout)findViewById(R.id.container);
View view = View.inflate(this, R.layout.layout_menu_item, null);
layout.addView(view);

Then we can figure out that B layout's setting wasn't set correctly. In other words, the setting wasn't executed. This inflate method ignored me :((

How to set correctly

First, I'd like to introduce and share inflate method to you.

Everybody knows inflate method is that show a view to the screen, but there are some ways we can use.

Method 1:

View v = View.inflate(this, R.layout.layout_your, root);
View v = getLayoutInflater().inflate(this, R.layout.layout_your, root);

Method 2:

View v = LayoutInflater.from(context).inflate(R.layout.layout_your, root);

Method 3:

View v = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE).inflate(R.layout.layout_your, root);

Actually the above of them are totally same things. If you dig deeper into the View.inflate, you can find out that LayoutInflater.from(context) is called inside View.inflate. And you dig into again LayoutInflater.from, you can see that (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) is called by LayoutInflater.from.

Briefly speaking, all of them are equal.

Summary

After I dug deeper into the SDK source code. I directly say brief summary.

There are three parameters of 'inflate(int resource, ViewGroup root, boolean attachToRoot)' method as below.

  1. resource: A layout id of a xml, ex: B layout(FrameLayout).
  2. root: This is a nullable parameter. ex: C root layout(LinearLayout).
  3. attachToRoot: Generate view add into root layout. ex: B layout(FrameLayout) add to C root layout(LinearLayout).

Here I will tell you directly about the parameters what we input then what kind of the view will show.

  1. If root == null, attachToRoot will be ineffective, then the parameter layout's setting won't be set. Return the parameter layout.
  2. If root != null AND attachToRoot == true, the parameter layout will be generated. Return the parameter layout.
  3. If root != null AND attachToRoot == false, the parameter layout will be generated and be set and add to the root automatically. Return the root layout.
  4. If don't set attachToRoot, attachToRoot != root as a parameter will be set automatically.

So if return value is that parameter layout(B layout), you need to call layout.addView(view); by yourself.

Better way to use

View view = LayoutInflater.from(this).inflate(R.layout.layout_menu_item, layout, false);
layout.addView(view);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment