I have previously an article has used onmeasure () to solve the ListView and Scollview display conflict issues, the blog address is as follows:
Onmeasure simple way to solve the problem of the ListView and Scollview conflict perfectly!
Here is a detailed explanation for the measurement of the view and some of the issues involved in onmeasure ():
First, the concept of Measurespec:
Measurespec provides a way to package and package packages by wrapping the Specmode and specsize into an int value to avoid excessive object memory allocations for ease of operation. Specmode and Specsize are also an int value, a set of Specmode and Specsize can be packaged as a measurespec, A measurespec can derive its original specmode and specsize in the form of unpacking.
The reader can only remember one sentence:
The value of the Measurespec is composed of specsize and Specmode, where the specsize record is the size, and the Specmode record is the specification.
Second, the specmode of three kinds of modes:
1. Exactly
When we specify the "Layout_width" property or the "Layout_height" property of a control as a specific value, such as "android:layout_width=" 200DP "," or "match_parent", This mode is used by the system.
2. At_most
When the Layout_width property of a control or the Layout_height property is set to Wrap_content, the size of the control generally varies with the size of the content, but no matter how large it is, it cannot exceed the size of the parent control.
3. UNSPECIFIED
Indicates that the developer can set the view to any size they wish, without any restrictions. This is a rare situation and is usually used when drawing a custom view.
Thirdly, what is the measurement of view related?
To explore its principle, first of all, and we have to explain a point, a view only need to measurespec determine, then in the onmeasure can measure its width, so we can directly convert the problem to "a view of the Measurespec how to determine it?" ”
Ordinary view of the measure process is passed by ViewGroup, here we do an explanation according to the source code, first look at the ViewGroup in the Measurechildwithmargins ():
[Java]View PlainCopy
- protected void Measurechildwithmargins (View child,
- int parentwidthmeasurespec, int widthused,
- int parentheightmeasurespec, int heightused) {
- FINAL Marginlayoutparams LP = (marginlayoutparams) child.getlayoutparams ();
- final int childwidthmeasurespec = Getchildmeasurespec (Parentwidthmeasurespec,
- Mpaddingleft + mpaddingright + lp.leftmargin + lp.rightmargin
- + widthused, lp.width);
- final int childheightmeasurespec = Getchildmeasurespec (Parentheightmeasurespec,
- Mpaddingtop + mpaddingbottom + lp.topmargin + lp.bottommargin
- + heightused, lp.height);
- Child.measure (Childwidthmeasurespec, Childheightmeasurespec);
- }
From this, we can see a view of the width of the high, all through the Getchildmeasurespec () This method obtained, then how does this come true? We may as well control+ left button to look inside, the code is as follows:
[Java]View PlainCopy
- Public static int getchildmeasurespec (int spec, int padding, int childdimension) {
- int specmode = Measurespec.getmode (spec);
- int specsize = measurespec.getsize (spec);
- int size = Math.max (0, specsize-padding);
- int resultsize = 0;
- int resultmode = 0;
- switch (specmode) {
- //Parent has imposed a exact size on US
- Case measurespec.exactly:
- if (childdimension >= 0) {
- ResultSize = childdimension;
- Resultmode = measurespec.exactly;
- } Else if (childdimension = = layoutparams.match_parent) {
- //Child wants to is our size. So is it.
- resultsize = size;
- Resultmode = measurespec.exactly;
- } Else if (childdimension = = layoutparams.wrap_content) {
- //child wants to determine its own size. It can ' t be
- //bigger than us.
- resultsize = size;
- Resultmode = Measurespec.at_most;
- }
- Break ;
- //Parent has imposed a maximum size on US
- Case Measurespec.at_most:
- if (childdimension >= 0) {
- //child wants a specific size ... so is it
- ResultSize = childdimension;
- Resultmode = measurespec.exactly;
- } Else if (childdimension = = layoutparams.match_parent) {
- //child wants to being our size, but we are not a fixed size.
- //constrain bigger than us.
- resultsize = size;
- Resultmode = Measurespec.at_most;
- } Else if (childdimension = = layoutparams.wrap_content) {
- //child wants to determine its own size. It can ' t be
- //bigger than us.
- resultsize = size;
- Resultmode = Measurespec.at_most;
- }
- Break ;
- //Parent asked to see how big we want to be
- Case measurespec.unspecified:
- if (childdimension >= 0) {
- //child wants a specific size ... let him has it
- ResultSize = childdimension;
- Resultmode = measurespec.exactly;
- } Else if (childdimension = = layoutparams.match_parent) {
- //Child wants to is our size ... find out how big it should
- // be
- ResultSize = View.susezerounspecifiedmeasurespec? 0:size;
- Resultmode = measurespec.unspecified;
- } Else if (childdimension = = layoutparams.wrap_content) {
- //child wants to determine its own size .... Find out how
- //Big it should be
- ResultSize = View.susezerounspecifiedmeasurespec? 0:size;
- Resultmode = measurespec.unspecified;
- }
- Break ;
- }
- return Measurespec.makemeasurespec (resultsize, Resultmode);
- }
The code is long, the reader can be more anxious--Don't be afraid, we don't need to fully understand its principle, we just need to know how the view measurement is done.
Seeing the three parameters in the source method and comparing the three values passed to Getchildmeasurespec () in the Measurechildwithmargins () method, we can quickly understand The measurement process for a view is determined by the measurespec of the parent layout and the view's layoutparams.
Readers can look at the following code in Measurechildwithmargins ():
[Java]View PlainCopy
- Final int childwidthmeasurespec = Getchildmeasurespec (Parentwidthmeasurespec,
- Mpaddingleft + mpaddingright + lp.leftmargin + lp.rightmargin
- + widthused, lp.width);
To measure the width of the Kobe Measurespec, you need to pass in 3 parameters:
First parameter: Measurespec of the width of the parent layout
The second parameter: the padding value of the Kobe Bureau, the margin value of the layoutparams of the Kobe Bureau
The third parameter: the width of the layoutparams of the Kobe Bureau
If the measurement process of the view is more in-depth curiosity, the recommended reader can look at the source code.
Copyright NOTICE: This article for Bo Master Xu Jiajia original article, reproduced please be sure to indicate the source. 51553703
"Reprint" Quick understanding of Android View Measurement onmeasure () and Measurespec