"Reprint" Quick understanding of Android View Measurement onmeasure () and Measurespec

Source: Internet
Author: User

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
  1. protected void Measurechildwithmargins (View child,
  2. int parentwidthmeasurespec, int widthused,
  3. int parentheightmeasurespec, int heightused) {
  4. FINAL Marginlayoutparams LP = (marginlayoutparams) child.getlayoutparams ();
  5. final int childwidthmeasurespec = Getchildmeasurespec (Parentwidthmeasurespec,
  6. Mpaddingleft + mpaddingright + lp.leftmargin + lp.rightmargin
  7. + widthused, lp.width);
  8. final int childheightmeasurespec = Getchildmeasurespec (Parentheightmeasurespec,
  9. Mpaddingtop + mpaddingbottom + lp.topmargin + lp.bottommargin
  10. + heightused, lp.height);
  11. Child.measure (Childwidthmeasurespec, Childheightmeasurespec);
  12. }
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
  1. Public static int getchildmeasurespec (int spec, int padding, int childdimension) {
  2. int specmode = Measurespec.getmode (spec);
  3. int specsize = measurespec.getsize (spec);
  4. int size = Math.max (0, specsize-padding);
  5. int resultsize = 0;
  6. int resultmode = 0;
  7. switch (specmode) {
  8. //Parent has imposed a exact size on US
  9. Case measurespec.exactly:
  10. if (childdimension >= 0) {
  11. ResultSize = childdimension;
  12. Resultmode = measurespec.exactly;
  13. } Else if (childdimension = = layoutparams.match_parent) {
  14. //Child wants to is our size.  So is it.
  15. resultsize = size;
  16. Resultmode = measurespec.exactly;
  17. } Else if (childdimension = = layoutparams.wrap_content) {
  18. //child wants to determine its own size. It can ' t be
  19. //bigger than us.
  20. resultsize = size;
  21. Resultmode = Measurespec.at_most;
  22. }
  23. Break ;
  24. //Parent has imposed a maximum size on US
  25. Case Measurespec.at_most:
  26. if (childdimension >= 0) {
  27. //child wants a specific size ... so is it
  28. ResultSize = childdimension;
  29. Resultmode = measurespec.exactly;
  30. } Else if (childdimension = = layoutparams.match_parent) {
  31. //child wants to being our size, but we are not a fixed size.
  32. //constrain bigger than us.
  33. resultsize = size;
  34. Resultmode = Measurespec.at_most;
  35. } Else if (childdimension = = layoutparams.wrap_content) {
  36. //child wants to determine its own size. It can ' t be
  37. //bigger than us.
  38. resultsize = size;
  39. Resultmode = Measurespec.at_most;
  40. }
  41. Break ;
  42. //Parent asked to see how big we want to be
  43. Case measurespec.unspecified:
  44. if (childdimension >= 0) {
  45. //child wants a specific size ... let him has it
  46. ResultSize = childdimension;
  47. Resultmode = measurespec.exactly;
  48. } Else if (childdimension = = layoutparams.match_parent) {
  49. //Child wants to is our size ... find out how big it should
  50. // be
  51. ResultSize = View.susezerounspecifiedmeasurespec?  0:size;
  52. Resultmode = measurespec.unspecified;
  53. } Else if (childdimension = = layoutparams.wrap_content) {
  54. //child wants to determine its own size .... Find out how
  55. //Big it should be
  56. ResultSize = View.susezerounspecifiedmeasurespec?  0:size;
  57. Resultmode = measurespec.unspecified;
  58. }
  59. Break ;
  60. }
  61. return Measurespec.makemeasurespec (resultsize, Resultmode);
  62. }

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
    1. Final int childwidthmeasurespec = Getchildmeasurespec (Parentwidthmeasurespec,
    2. Mpaddingleft + mpaddingright + lp.leftmargin + lp.rightmargin
    3. + 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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.