Detailed explanation and analysis of Android layoutinflator. Inflate()

Detailed explanation of Android layoutinflator. Inflate()

Understand layoutinflator. Inflate() in depth

Because it's easy to get used to formulaic preset code, sometimes we ignore very elegant details. This is how layoutinflator and its way of filling the view in oncreateview () of fragment give me this feeling. This class is used to convert XML files into corresponding ViewGroup and widget controls. I tried to find relevant explanations in Google's official documents and other discussions on the network, and found that many people not only did not know the details of layoutinflator's inflate () method, but even misused it.

The confusion here is largely due to the vague documents on attachtoroot (that is, the third parameter of the inflate () method) on Google:

Should the filled layer be attached inside the root parameter? If false, the root parameter applies only to subclasses that create the correct layoutparams for the XML root element view.

If attachtoroot is true, the layout file of the first parameter will be filled and attached to the ViewGroup specified by the second parameter. Method returns the combined view. The root element is the second parameter ViewGroup. If false, the layout file specified by the first parameter will be filled and returned as a view. The root element of this view is the root element of the layout file. Whether true or false, the layoutparams of the ViewGroup is required to correctly measure and place the view object generated by the layout file.

If attachtoroot is passed in true, the view filled by the layout file will be directly added to the ViewGroup, while if false is passed in, the created view will be added to the ViewGroup in other ways.

Let's give more examples of the two cases for a deeper understanding.

Attachtoroot is true

Suppose we write a button in the XML layout file and specify the width and height as match_ parent。

Now we want to dynamically add this button to the LinearLayout of the fragment or activity. If LinearLayout here is already a member variable mlinearlayout, we only need to achieve the goal through the following code:

We specify the layout resource file to populate the button, and then we tell the layouteinflator that we want to add the button to mlinearlayout. Here, the layoutparams type of button is linearlayout.layoutparams.

The following code has the same effect. The inflate () method of the two parameters of layoutinflator automatically sets attachtoroot to true.

Another way to pass true in attachtoroot is to use a custom view. Let's look at an example where the root element in the layout file has a label. The tag identifies the root of the layout file. There are many types of viewgroups.

This is a good example of using attachtoroot. In this example, the layout file does not have ViewGroup as the root element, so we specify our customized LinearLayout as the root element. If the layout file has a FrameLayout as the root element instead of, the FrameLayout and its child elements can be filled normally, and then they will be added to the LinearLayout. LinearLayout is the root ViewGroup, which contains the FrameLayout and its child elements.

Attachtoroot is false

Let's see when attachtoroot should be false. In this case, the view specified by the first parameter in the inflate () method will not be added to the ViewGroup specified by the second parameter.

Recall the button in the example just now. We want to add a custom button to mlinearlayout through the layout file. When attachtoroot is false, we can still add the button to mlinearlayout, but we need to do it ourselves.

These two lines of code are equivalent to the one line of code when attachtoroot is true just now. By passing in false, we tell layoutinflator that we don't want to add the view to the root element ViewGroup for the time being, which means we'll add it later. In this example, the addView () method is called after inflate ().

In the example where attachtoroot is set to false, there is too much code due to manually adding views to the ViewGroup. It is easier to add a button to the LinearLayout or set attachtoroot to true directly with one line of code. Let's take a look at the case where attachtoroot must pass in false.

The child elements of each recyclerview should be filled when attachtoroot is set to false. Here, the child views are populated in oncreateviewholder().

Recyclerview is responsible for deciding when to display its child views, which is not up to us. Attachtoroot should be set to false in any case where we are not responsible for adding a view to the ViewGroup.

When populating and returning the view in the oncreateview () method of the fragment, set attachtoroot to false. If true is passed in, an IllegalStateException will be thrown because the specified child view already has a parent view. You need to specify where to put the fragment view into the activity, and adding, removing or replacing fragments is the task of the fragment manager.

Root in the above code_ ViewGroup is the container used to place fragments in the activity. It will be passed into oncreateview () as the second parameter in the inflate () method. It is also the ViewGroup you passed in in the insert () method. The fragment manager will add the fragment's view to the ViewGroup. You don't want to add it twice.

The question is: if we don't need to add the view to the ViewGroup in oncreateview(), why pass in the ViewGroup? Why does the populate () method have to pass in the root ViewGroup?

The reason is that it is not necessary to add the newly filled view to the ViewGroup immediately. We still need the layoutparams of this parent element to determine the size and position of the view when adding it in the future.

You will encounter some incorrect suggestions on the Internet. Some people will suggest that if you set attachtoroot to false, you directly pass the root ViewGroup into null. However, if there is a parent element, it should be passed in.

Lint will warn you not to say null is passed in as root. Your app won't hang up, but it may behave abnormally. When your child view does not have the correct layoutparams, it will calculate itself through generatedefaultlayoutparams).

You may not want these default layoutparams. The layoutparams you specify in XML will be ignored. We may have specified that the child view should fill the width of the parent element, but the parent view is wrapped_ Content makes the final view much smaller.

The following is a case where no ViewGroup is passed in as root to the inflate () method. When creating a custom view for alertdialog, the parent element cannot be accessed.

In this case, null can be passed in as root ViewGroup. Later, I found that alertdialog still rewrites layoutparams and sets various parameters to match_ parent。 However, the rule is still passed in when a ViewGroup can be passed in.

Avoid crashes, anomalies and misunderstandings

I hope this article can help you avoid crashes, abnormal expressions and misunderstandings when using layoutinflator. Here are the main points of the article:

Thank you for reading, hope to help you, thank you for your support to this site!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>