Use the correct posture of Layoutinflater
When you first approached Android, you knew that Layoutinflater was used to generate a corresponding view of the layout file. At that time, Mengmengdongdong knew it was necessary to pass a LayoutID a parent parameter and a false parameter. That's when it was used, At the beginning, it was good. Until later with the further study of Android Development found that the two parameters of Layoutinflater are big doorways inside.
Then this blog post can be said to be a summary of my use of layoutinflater.
How do I add a view to ViewGroup?
Before we discuss how to use Layoutinflater, let's think about this interesting question. How do we add a view to ViewGroup?
分别有两种办法(归根到底还是一种而已,事实上以上第一种方法总归还是通过第二种办法实现的)
We focus on the two addview methods of the Purple box. The difference between the two methods is whether the Layoutparam parameter is passed. Why is this parameter passed? Why not be thorough?
Good understanding, not delivery then I will help you to construct one by default is finished.
See that the code actually adds a view to a viewgroup without using AddView (view child). The view that needs to be added comes with layoutparam so I take it out and use it in the process of adding, If view is not attached layoutparam then I will help you construct a viewgroup.layout.
There is a very serious problem here. Use the Generatedefaultlayoutparams function to generate a Viewgroup.layoutparam object in the ViewGroup code.
But you change to ViewGroup subclass LinearLayout (of course other subclasses can also, here take linearlayout as explanation). You'll find the Generatedefaultlayoutparams function rewritten! And it's not about generating Viewgroup.layoutparam objects but Linearlayout.layouparam objects!
What the hell am I trying to say? I want you to know. A view added to the ViewGroup is required to use the corresponding Layoutparam.
You can do a little test. Add a view that holds the Viewgroup.layoutparam object internally to LinearLayout.
Looking at some of LinearLayout's code snippets, LinearLayout will take out the sub-view that he contains. and get the layoutparam of the child view to Linelayout.layoutparam and use the corresponding attributes inside.
LineLayout.LayoutParam继承ViewGroup.MarginLayoutParamsViewGroup.MarginLayoutParams继承ViewGroup.LayoutParamsViewGroup.MarginLayoutPara添加leftMargintopMarginrightMargin,bottomMargin属性
In fact, the program did not get an error. And the normal run up ... (How do you not follow the plot development?)
Find out where the key points are at the end of the problem.
Subclasses inheriting ViewGroup will override the Generatelayoutparams function. The function of Generatelayoutparams is to convert the Layoutparam object into a corresponding Generatelayoutparams object. For example , when calling the Linearlayout#addview function.
LinearLayout#addView(view,new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT))
If the Relativelayout.layoutparams object that was passed in when the call AddView is not converted to Linearlayout.layoutparams, Then there must be a problem when LinearLayout uses this object. Of course, this loading work is given to the Generatelayoutparams function.
If the AddView is not passed in the layout of the Layoutparams will certainly discard some properties. Like you can't play that way?
GridLayout. LayoutparamsParams;params = new GridLayout. Layoutparams(New ViewGroup. Layoutparams(ViewGroup. Layoutparams. WRAP_content, ViewGroup. Layoutparams. WRAP_content));Params. Setgravity(Gravity. Left);LinearLayout layout = (linearlayout) Findviewbyid (R. ID. Activity_main);Layout. AddView(View,params);
And then it's our main course.
Layoutinflater detailed
Generate the view by Layoutinflater R.layout.activity_main and call Setcontentview.
publicclass MainActivity extends AppCompatActivity { @Override protectedvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); View view = LayoutInflater.from(thisfalse); setContentView(view); }}
It can be seen that the usage and the following usage are in fact no different.
publicclass MainActivity extends AppCompatActivity { @Override protectedvoidonCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
The first approach is that we call layoutinflater ourselves to create the view and call Setcontentview into the Contentview. The second option is to Setcontentview internally call Layoutinflater to generate the layout and Add the layout to the Contentview inside the inflater.
Parameters of the Inflate function
The inflate function is simple and rude, and the function generates a view based on the layout you pass in. and returns a view.
Next look at the three parameters of the inflate function
Resource parameters
It is well known that the resource parameter is the layout file ID that needs parsing.
Attachtoroot parameters
The Attachtoroot parameter is interesting, and there are two subtle changes to its settings. And the use of Layoutinflater actually understand attachtoroot parameters can be said to have mastered the 80%.
First, the Attachtoroot parameter literally shows the effect of the white parameter. Is whether to add the view to the viewgroup specified by the root parameter after using resource to generate the view.
Second, the Attachtoroot parameter determines what the return value returns. If Attachtoroot is true then the inflate return value is the value passed by the root parameter. If Attachtoroot is false, Then the return value is the view generated by the resource resource file.
Here are two scenarios, what if root is null? If Root is basically ignoring the value of the Attachtoroot parameter, return the view generated by the resource resource file directly.
This is the only place to change resutl, or return to Rootviewgroup.
Root parameter
Through the above analysis of the previous two parameters, you should also know that the root parameter is a viewgroup just.
But look at the code and you'll find an interesting place, The root parameter specifies which viewgroup to add to the view that is generated by the resource resource file. And the inflate function uses the ViewGroup specified by the root parameter to generate the Layoutparam parameter.
It looks interesting! In fact, the first part of the analysis, we know that using ViewGroup to generate Layoutparam actually does not have much meaning.
The correct posture of Layoutinflater
Layoutinflater the question of using the core is whether the view I generated from the resource resource file is added to the rootviregroup. This requirement is determined, and the layoutinflater wants to use it.
First, if I just create a view, I don't need to add it to rootviregroup. You have the following three options
layoutinflater.from (this) .inflate (R.layout .activity _main, NULL, true) Layoutinflater.from (This) .inflate (R.layout .activity _main, NULL, FALSE) Layoutinflater.from (This) .inflate (R.layout .activity _main, ViewGroup, false)
The first and second usages are no different because the root parameter is null. It doesn't make sense for you to pass any value to Attachtoroot. And the return value is the view generated by the resource resource file.
There is a small difference between the third method and the previous two. Because Root is specified, The inflate function then calls the root object's Generatelayoutparams function to generate a Layoutparam object and injects it into the view generated by the resource resource file. Of course, the return value is the same as the previous two.
Second, if I just generate a view and add it to rootviregroup. You have only one choice.
LayoutInflater.from(this).inflate(R.layout.activity_main, viewGroup, true);
- This time the view generated by the resource resource file is added to the ViewGroup and the return value becomes ViewGroup.
So you should know what it's like to use Layoutinflater's correct posture?
So one digression, what is the spirit of the inflate function?
The inflate function actually encapsulates an XML parser, parsing the name and attributes of the node by parsing the XML file. Then find the class of the view according to the name, call the class's constructor (and, of course, pass the parsed attribute to the constructor) Generate the view. And then constantly recursively know to parse all the nodes. (A view tree is generated based on the hierarchy)
Use the correct posture of Layoutinflater