What Does the Layoutinflater Attachtoroot Parameter Mean

What is the use of attach to root in layout inflater?

I myself was also confused about what was the real purpose of attachToRoot in inflate method. After a bit of UI study, I finally got the answer:

parent:

in this case is the widget/layout that is surrounding the view objects that you want to inflate using findViewById().

attachToRoot:

attaches the views to their parent (includes them in the parent hierarchy), so any touch event that the views recieve will also be transfered to parent view. Now it's upto the parent whether it wants to entertain those events or ignore them. if set to false, they are not added as direct children of the parent and the parent doesn't recieve any touch events from the views.

Hope this clears the confusion

Clarification about layout inflater -attach to root?

No, something is missed!

When you pass true as 'attach to root', inflater will inflate specified layout (represented by its ID) and then attach it to root of parent and finally return the parent

But when you left 'attach to root' to false. the parent hierarchy won't changed and only inflated layout will be returned.

a function of android:how to use the function of inflate(int resource, ViewGroup root, boolean attachToRoot)

Inflate is used to add a view, especially used for inflating fragments inside an activity. ViewGroup root is the parent view in which you want to inflate your view.
If you are using this function to inflate a fragment then use it like this:


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_name,container,false);
return view;
}

If this does not answer your query then let me know in what context are you exactly using inflate.

Why attach to a root ViewGroup when inflating a custom toast message?

A Rule of Thumb

When you use the method inflate(), the third parameter has three options:

  1. Passing true: That means, you are asking to attach the first parameter (view) in the inflate() method to the second parameter (i.e. ViewGroup).

    We use it in scenarios such that if you have a Button in one separate XML file that you want to attach to Layout (it could be your main one).

    Example:

    inflater.inflate(R.layout.my_custom_button, myLinearLayout, true);
  2. Passing false: That means, you are asking the inflate() method NOT to attach the first view to the second, but in this case, you have to add it yourself after.

    Example:

    Button button = (Button) inflater.inflate(R.layout.my_custom_button, myLinearLayout, false);
    myLinearLayout.addView(button);

    It does the same like the first scenario, so no point of passing false here. However, there are scenarios when you should pass the third parameter as false such that when you are not the one responsible for attaching our layout file’s View to its root ViewGroup.

    Example:

    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(getActivity());
    View view = inflater.inflate(android.R.layout.list_item_recyclerView, parent, false);
    return new ViewHolder(view);
    }
  3. Passing null:It is not recommended at all, however, your app won’t crash in this scenario, but it can misbehave. You app will try to determine the correct LayoutParams for the root ViewGroup by using the generateDefaultLayoutParams.
    (which might not be what you desired).


For more details, refer to the source


UPDATE

After reading your comment below, I see now where you get confused exactly with this matter:
You seem aware of the above rules, but your only confusion is: why we are passing a View as root to the second parameter in inflate() though it is already a root in the XML resource that we passed in the first parameter.

Well, that is in simple words because this is how inflate() method works:
Understanding why we need the second parameter in inflate() in general will solve this problem for you:

In addition to what I wrote above: The second parameter in inflate() is the root which is an optional view to be the parent of the generated hierarchy (if 3rd parameter is true), OR to be an OBJECT that PROVIDES the LayoutParams values for ROOT of the RETURNED hierarchy.

So inflate() method will always refer to the second parameter after generating the hierarchy of the view in the provided XML file at the first parameter.


Conclusion

In your particular scenario, we are not passing false because that will lead to inflate call IGNORING the layout parameters from the XML.

what does 3rd parameter of public View inflate (int resource, ViewGroup root, boolean attachToRoot) do?

What does public View inflate (int resource, ViewGroup root, boolean attachToRoot) really means ?

It points to the layout resource you want to inflate. The second parameter is the root view of the hierarchy you are inflating the resource to attach to. When the third parameter is present, it governs whether or not the inflated view is attached to the supplied root after inflation.

The last two parameters that can cause a bit of confusion. With the two parameter version of this method, LayoutInflater will automatically attempt to attach the inflated view to the supplied root. However, the framework has a check in place that if you pass null for the root it bypasses this attempt to avoid an application crash.

In most cases it will throw an Exception later on if LayoutInflater is allowed to automatically attach the inflated view to the root.

So why this ViewGroup is given if we are not supposed to attach to it?

It turns out the parent view as a very important part of the inflation process because it is necessary in order to evaluate the LayoutParams declared in the root element of the XML being inflated. Passing nothing here is akin to telling the framework “Sorry because I don’t know what parent this view will be attached to actually”.

reference

Why does LayoutInflater ignore the layout_width and layout_height layout parameters I've specified?

I've investigated this issue, referring to the LayoutInflater docs and setting up a small sample demonstration project. The following tutorials shows how to dynamically populate a layout using LayoutInflater.

Before we get started see what LayoutInflater.inflate() parameters look like:

  • resource: ID for an XML layout resource to load (e.g., R.layout.main_page)
  • root: Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
  • attachToRoot: Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.

  • Returns: The root View of the inflated hierarchy. If root was supplied and attachToRoot is true, this is root; otherwise it is the root of the inflated XML file.

Now for the sample layout and code.

Main layout (main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</LinearLayout>

Added into this container is a separate TextView, visible as small red square if layout parameters are successfully applied from XML (red.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="#ff0000"
android:text="red" />

Now LayoutInflater is used with several variations of call parameters

public class InflaterTest extends Activity {

private View view;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);
ViewGroup parent = (ViewGroup) findViewById(R.id.container);

// result: layout_height=wrap_content layout_width=match_parent
view = LayoutInflater.from(this).inflate(R.layout.red, null);
parent.addView(view);

// result: layout_height=100 layout_width=100
view = LayoutInflater.from(this).inflate(R.layout.red, null);
parent.addView(view, 100, 100);

// result: layout_height=25dp layout_width=25dp
// view=textView due to attachRoot=false
view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
parent.addView(view);

// result: layout_height=25dp layout_width=25dp
// parent.addView not necessary as this is already done by attachRoot=true
// view=root due to parent supplied as hierarchy root and attachRoot=true
view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
}
}

The actual results of the parameter variations are documented in the code.

SYNOPSIS: Calling LayoutInflater without specifying root leads to inflate call ignoring the layout parameters from the XML. Calling inflate with root not equal null and attachRoot=true does load the layout parameters, but returns the root object again, which prevents further layout changes to the loaded object (unless you can find it using findViewById()).
The calling convention you most likely would like to use is therefore this one:

loadedView = LayoutInflater.from(context)
.inflate(R.layout.layout_to_load, parent, false);

To help with layout issues, the Layout Inspector is highly recommended.



Related Topics



Leave a reply



Submit