What Does It Mean to Inflate a View from an Xml File

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:

  1. Get an instance of the LayoutInflater
  2. Specify the XML to inflate
  3. Use the returned View
  4. 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



Leave a reply



Submit