What does LayoutInflater in Android do?
The LayoutInflater class is used to instantiate the contents of layout XML files into their corresponding View objects.
In other words, it takes an XML file as input and builds the View objects from it.
What does LayoutInflator
do?
When I first started Android programming, I was really confused by LayoutInflater
and findViewById
. Sometimes we used one and sometimes the other.
LayoutInflater
is used to create a newView
(orLayout
) object from one of your xml layouts.findViewById
just gives you a reference to a view than has already been created. You might think that you haven't created any views yet, but whenever you callsetContentView
inonCreate
, the activity's layout along with its subviews gets inflated (created) behind the scenes.
So if the view already exists, then use findViewById
. If not, then create it with a LayoutInflater
.
Example
Here is a mini project I made that shows both LayoutInflater
and findViewById
in action. With no special code, the layout looks like this.
The blue square is a custom layout inserted into the main layout with include
(see here for more). It was inflated automatically because it is part of the content view. As you can see, there is nothing special about the code.
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
Now let's inflate (create) another copy of our custom layout and add it in.
LayoutInflater inflater = getLayoutInflater();View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
To inflate the new view layout, all I did was tell the inflater the name of my xml file (my_layout
), the parent layout that I want to add it to (mainLayout
), and that I don't actually want to add it yet (false
). (I could also set the parent to null
, but then the layout parameters of my custom layout's root view would be ignored.)
Here it is again in context.
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // inflate the main layout for the activity setContentView(R.layout.activity_main); // get a reference to the already created main layout LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_main_layout); // inflate (create) another copy of our custom layout LayoutInflater inflater = getLayoutInflater(); View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false); // make changes to our custom layout and its subviews myLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorAccent)); TextView textView = (TextView) myLayout.findViewById(R.id.textView); textView.setText("New Layout"); // add our custom layout to the main layout mainLayout.addView(myLayout); }}
Notice how findViewById
is used only after a layout has already been inflated.
Supplemental Code
Here is the xml for the example above.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main_layout" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <!-- Here is the inserted layout --> <include layout="@layout/my_layout"/></LinearLayout>
my_layout.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="100dp" android:layout_height="100dp" android:background="@color/colorPrimary"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:padding="5dp" android:textColor="@android:color/white" android:text="My Layout"/></RelativeLayout>
When do you need LayoutInflater
- The most common time most people use it is in a
RecyclerView
. (See theseRecyclerView
examples for a list or a grid.) You have to inflate a new layout for every single visible item in the list or grid. - You also can use a layout inflater if you have a complex layout that you want to add programmatically (like we did in our example). You could do it all in code, but it is much easier to define it in xml first and then just inflate it.
When you use a custom view in a ListView
you must define the row layout.You create an xml where you place android widgets and then in the adapter's code you have to do something like this:
public MyAdapter(Context context, List<MyObject> objects) extends ArrayAdapter { super(context, 1, objects); /* We get the inflator in the constructor */ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) { View view; /* We inflate the xml which gives us a view */ view = mInflater.inflate(R.layout.my_list_custom_row, parent, false); /* Get the item in the adapter */ MyObject myObject = getItem(position); /* Get the widget with id name which is defined in the xml of the row */ TextView name = (TextView) view.findViewById(R.id.name); /* Populate the row's xml with info from the item */ name.setText(myObject.getName()); /* Return the generated view */ return view;}
Read more in the official documentation.