What does it mean to inflate a view from an xml file?
When you write an XML layout, it will be inflated by the Android OS which basically means that it will be rendered by creating view object in memory. Let's call that implicit inflation (the OS will inflate the view for you). For instance:
class Name extends Activity{
public void onCreate(){
// the OS will inflate the your_layout.xml
// file and use it for this activity
setContentView(R.layout.your_layout);
}
}
You can also inflate views explicitly by using the LayoutInflater
. In that case you have to:
- Get an instance of the
LayoutInflater
- Specify the XML to inflate
- Use the returned
View
- Set the content view with returned view (above)
For instance:
LayoutInflater inflater = LayoutInflater.from(YourActivity.this); // 1
View theInflatedView = inflater.inflate(R.layout.your_layout, null); // 2 and 3
setContentView(theInflatedView) // 4
What does LayoutInflater in Android do?
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);
}
@Override
public 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.
What does inflater.inflate() do?
You have a View
defined in your xml file. E.g. you have a layout
for a list row.
You want to create a View
from that xml. E.g. your ListAdapter
requires you to create a View
for a list row in ListAdapter.getView()
;
So by using inflater.inflate()
you create your View
from your XML file.
There's also a static method View.inflate()
which does the same.
Why should I use LayoutInflater to obtain a view if I can directly obtain it using findViewById()
Its not the same thing.
Inflate takes a Layout xml file and makes a View out of it.
findViewById looks for a view inside a viewGroup.
In your example:
Your first code will inflate R.layout.custom_toast
and attach it to the parent ViewGroup R.id.toast_layout_root
Your second code will take the R.id.toast_layout_root
ViewGroup and set it as the layout of the dialog.
Basically your first code will end up with R.layout.custom_toast
as the dialog layout while your second code will use R.id.toast_layout_root
as the dialog layout.
Its clearly not the same thing, findViewById needs an already inflated View.
Hope this helps.
What happens behind the scenes when an xml is inflated?
Check out the source for the LayoutInflater
. It's an abstract class, a concrete instance of which is obtained through getLayoutInflater()
.
In essence, the inflater creates a root view object (the root view group of the inflated XML), then does two passes through the XML tree to attach each child view. This is done recursively to handle 'include' and to fix up references between child views, for example in RelativeLayout
, and is done top to bottom.
The first pass constructs the tree by instantiating each of the child views, top down recursively, and passes the XML attributes to the view constructor telling the view how big it should be. It then calls measure()
for each child passing in restrictions determined by the parent (e.g. RelativeLayout with 2 child views each requesting match_parent) using a measure specifications object and asks the view how big it wants to be. If the view is itself a view group, it will use the same algorithm to measure it's children.
The second pass is the layout pass when layout()
is called on each child to position itself within the view. The parent positions the view using the measurements calculated in the measure pass. onDraw()
is called and is passed a Canvas created from the DecorView
backing bitmap.
The finalised tree is then ready to pass to the window manager which is done by setContentView()
or addContentView()
.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/LayoutInflater.java#LayoutInflater
How to inflate one view with a layout
I'm not sure I have followed your question- are you trying to attach a child view to the RelativeLayout? If so you want to do something along the lines of:
RelativeLayout item = (RelativeLayout)findViewById(R.id.item);
View child = getLayoutInflater().inflate(R.layout.child, null);
item.addView(child);
android how to inflate one view defined in a layout file (not whole file)
Can they put into one layout file and inflated separately?
No. When you inflate a layout resource, you are inflating everything inside that file.
Different view components(e.g. Button, TextView) will be created (inflated) depending on different conditions.
It sounds like you might be able to achieve what you want by using ViewStub
tags.
To do this, you would create your main layout file as normal. However, anywhere you want to have dynamic content, you add a <ViewStub>
tag. Then, in Java/Kotlin, after you inflate your main layout, you can inflate different views into the ViewStub.
main_layout.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Header"/>
<ViewStub
android:id="@+id/stub"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Footer"/>
</LinearLayout>
button.xml
<Button
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CLICK ME">
text.xml
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Can't click me">
MainActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
ViewStub stub = findViewById(R.id.stub);
if (isUseButton) {
stub.setLayoutResource(R.layout.button);
} else {
stub.setLayoutResource(R.layout.text);
}
stub.inflate();
}
Are Views automatically inflated?
You just have to inflate an xml layout, and then all the viewgroups and views (buttons,textview,edittext,etc.) will automatically be shown.
So in an Activity class, oncreate method has a line SetContentview(), this inflates the xml layout.
Related Topics
Flutter Does Not Find Android Sdk
Apk Location in New Android Studio
Drawable-Hdpi, Drawable-Mdpi, Drawable-Ldpi Android
How to Detect When the User Has Changed the Clock Time on Their Device
Close Application and Remove from Recent Apps/
Android: Overlay on Android Camera Preview
Setresult Does Not Work When Back Button Pressed
Android Studio - Creating Modules Without Copying Files
How to Change Bitmap Image Color in Android
Google Glass Gdk: How to Communicate with Android Device
The Process of the Service Is Killed After the Application Is Removed from the Application Tray
How to Update My Adt in Eclipse
How to Check Whether the Sim Card Is Available in an Android Device
Using Android Intent.Action_Send for Sending Email
Any Way to Link to the Android Notification Settings for My App