[Go] Three cases show you the differences between the two parameters of the inflate method and the three parameters in LayoutInflater,
I think many people know more or less about the inflate parameter. There are also many articles on the Internet about this, however, the boring theory or translation has made many friends feel overwhelmed after reading it. so, today I want to use three cases to help them thoroughly understand this stuff. In this blog, we only use the source code. The source code will be interpreted in the next blog.
The inflate method can be divided into two types: constructor of three parameters and constructor of two parameters. There are further subdivisions in these two categories. OK, then we will demonstrate all kinds of situations.
1. The inflate method of the three parameters
The method header is as follows:
[Java]View plain copy
- Public View inflate (@ LayoutRes int resource, @ Nullable ViewGroup root, boolean attachToRoot)
Well, there are three main cases:
1.1 root is not null, and attachToRoot is true
When root is not null and attachToRoot is true, the layout specified by resource is added to root, each attribute of the root node of the layout specified by resource is valid during addition. In the following example, the layout of my Activity is as follows:
[Java]View plain copy
- <? Xml version = "1.0" encoding = "UTF-8"?>
- <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
- Xmlns: tools = "http://schemas.android.com/tools"
- Android: layout_width = "match_parent"
- Android: layout_height = "match_parent"
- Android: orientation = "vertical"
- Android: id = "@ + id/ll"
- Tools: context = "org. sang. layoutinflater. MainActivity">
- </LinearLayout>
I also have a layout linearlayout. xml as follows:
[Java]View plain copy
- <? Xml version = "1.0" encoding = "UTF-8"?>
- <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
- Android: id = "@ + id/ll"
- Android: layout_width = "200dp"
- Android: layout_height = "200dp"
- Android: background = "@ color/colorPrimary"
- Android: gravity = "center"
- Android: orientation = "vertical">
- <Button
- Android: layout_width = "wrap_content"
- Android: layout_height = "wrap_content"/>
- </LinearLayout>
Now I want to add this linearlayout. xml layout file to my activity layout, so I can do this:
[Java]View plain copy
- @ Override
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
- SetContentView (R. layout. activity_main );
- LinearLayout ll = (LinearLayout) findViewById (R. id. ll );
- LayoutInflater inflater = LayoutInflater. from (this );
- Inflater. inflate (R. layout. linearlayout, ll, true );
- }
Friends noticed that I did not write the code to add the inflate View to ll, but the linearlayout layout file has already been added, because my third parameter is set to true, add the layout specified by the first parameter to the View of the second parameter. The final result is as follows:
If I write such a line of code as follows:
[Java]View plain copy
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
- SetContentView (R. layout. activity_main );
- LinearLayout ll = (LinearLayout) findViewById (R. id. ll );
- LayoutInflater inflater = LayoutInflater. from (this );
- View view = inflater. inflate (R. layout. linearlayout, ll, true );
- Ll. addView (view );
- }
When this occurs, the system throws the following exception:
[Java]View plain copy
- Java. lang. IllegalStateException: The specified child already has a parent. You must call removeView () on the child's parent first.
This is because when the third parameter is true, the View specified by the first parameter is automatically added to the View specified by the second parameter.
1.2 root is not null, and attachToRoot is false
If root is not null and attachToRoot is false, it means that the View specified by the first parameter is not added to root. At this time, some friends may have doubts, since it is not added to the root, why should I write so much? Can I directly add null to the second parameter? Otherwise, another question is involved: what is the meaning of the layout_width and layout_height that we specify for the control during development? This attribute indicates the size of a control in the container, that is, the control must be in the container. This attribute makes sense, otherwise it is meaningless. This means that if I load linearlayout directly without specifying a parent layout for it, the layout_width and layout_height attributes of the root node in the inflate layout will expire (because linearlayout will not be in any container at this time, the width and height of the root node will naturally expire ). If I want to make the root node of linearlayout valid and do not want it to be in a container, I can set root not to null, but attachToRoot to false. In this way, the purpose of specifying root is very clear, that is, root will assist the root node of linearlayout to generate layout parameters, only for this purpose. OK, or the layout File above. What if I want to add it to the layout of the activity?
[Java]View plain copy
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
- SetContentView (R. layout. activity_main );
- LinearLayout ll = (LinearLayout) findViewById (R. id. ll );
- LayoutInflater inflater = LayoutInflater. from (this );
- View view = inflater. inflate (R. layout. linearlayout, ll, false );
- Ll. addView (view );
- }
Note: At this time, I need to manually add the inflate loaded view to the ll container. Because the last parameter of inflate is false, linealayout is not added to ll. The display effect is the same as the above, and no texture is attached.
1.3 root is null
When the root value is null, whether the value of attachToRoot is true or false, the display effect is the same. When root is null, it means that I do not need to add the layout specified by the first parameter to any container, it also indicates that no container is used to generate layout parameters for the root node of the layout specified by the first parameter. I still use the linearlayout mentioned above. Let's look at the following code:
[Java]View plain copy
- Protected void onCreate (Bundle savedInstanceState ){
- Super. onCreate (savedInstanceState );
- SetContentView (R. layout. activity_main );
- LinearLayout ll = (LinearLayout) findViewById (R. id. ll );
- LayoutInflater inflater = LayoutInflater. from (this );
- View view = inflater. inflate (R. layout. linearlayout, null, false );
- Ll. addView (view );
- }
When the second parameter is null and the third parameter is false (even if it is true, the display effect is the same. Here, false is used as an example ), because the inflate method does not add linearlayout to a container, I need to add it manually. In addition, because linearlayout is not in a container, therefore, the width and height attributes of the root node become invalid, and the display effect is as follows:
Dear friends, no matter what width or height I set for the root node of linearlayout at this time, it is ineffective. It is a wrapped button. If I modify the button, the button will change immediately, because the button is in a container.
2. The inflate method of the two parameters is very simple. Let's take a look at the source code:
[Java]View plain copy
- Public View inflate (XmlPullParser parser, @ Nullable ViewGroup root ){
- Return inflate (parser, root, root! = Null );
- }
This is the inflate method of the two parameters. Note that the two parameters actually call the three parameters. The inflate method of the two parameters is divided
There are two situations:
1. The root is null, which is equivalent to the case described in section 1.3.
2. root is not null, which is equivalent to the case described in section 1.1.3. Why does the width and height attribute of the root node of the Activity layout take effect?
We have already finished the inflate method. Some friends may have another question. Why does the width and height attribute of the root node of the Activity layout take effect? In fact, the reason is very simple. In most cases, an Activity page consists of two parts (the Android version number and the application topic will affect the Activity page. Here we take the common page as an example ), there is a top-level View in our page called DecorView, which contains a vertical LinearLayout. LinearLayout consists of two parts: the first part is the title bar, the second part is the content bar, and the content bar is a FrameLayout, when we call setContentView in the Activity, we add the View to the FrameLayout. Therefore, it seems that the root layout of the Activity is special, but it is not.