The View.onmeasure method of Android

Source: Internet
Author: User

The view appears on the screen to go through measure (calculation) and layout.

1. When do I call the Onmeasure method?

called when the control's parent element is about to place the control. The parent element asks the child control a question, "How much place do you want to use?" ", and then pass in two parameters--widthmeasurespec and Heightmeasurespec.

These two parameters indicate the space that the control can obtain and the metadata about the space description.

A better way is to pass the height and width of the view to the Setmeasureddimension method so that you can tell the parent control how much place you need to place the child controls.

the next code snippet shows how to rewrite the onmeasure. Note that the local empty method that is called is to calculate the height and width. They translate the values of Widthheightspec and heightmeasurespec and calculate the appropriate height and width values.

Java code:

    1. @Override
    2. protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
    3. int measuredheight = Measureheight (Heightmeasurespec);
    4. int measuredwidth = Measurewidth (Widthmeasurespec);
    5. Setmeasureddimension (Measuredheight, measuredwidth);
    6. }
    7. private int measureheight (int measurespec) {
    8. Return measured widget height.
    9. }
    10. private int measurewidth (int measurespec) {
    11. Return measured widget width.
    12. }
Copy Code


Boundary parameters--widthmeasurespec and Heightmeasurespec, the reason for efficiency is passed in as integers. Before they are used, the first thing to do is to use the static method of the Measurespec class GetMode and getsize to translate the solution, as shown in the following fragment:

Java code:

    1. int specmode = Measurespec.getmode (Measurespec);
    2. int specsize = measurespec.getsize (Measurespec);
Copy Code


according to the value of Specmode, (Measurespec 3 modes are unspecified, exactly and At_most respectively)


If the at_most,specsize represents the largest available space;
If the exactly,specsize represents a precise size;
In the case of unspecified, there is no reference to the size of the control.

2, then these patterns and we usually set the layout parameters fill_parent, wrap_content have what relationship?

The code tests know that when we set width or height to fill_parent, the measure method in which the container calls the child view in the layout is exactly because the child view occupies the space of the remaining container, so its size is deterministic.

When set to Wrap_content, the container passes in the At_most, indicating the maximum size of the child view, so that the child view will set its own size according to this limit. When the size of the child view is set to an exact value, the container passes in exactly, and Measurespec's unspecified mode is not currently found under what circumstances.
   
The default behavior of the Onmeasure method of the view is that when the pattern is unspecified, the size is mminwidth (usually 0) or the minimum size of the background drawable, when the mode is exactly or at_most, The size is set to the size of the incoming measurespec.
   
One idea that needs to be corrected is that fill_parent should be a sub-view that takes up space for the rest of the container, without overwriting the other view spaces that were previously laid out, and of course the layout sub-view has no space to allocate, so the Fill_parent property is important for the layout order. It was thought that the space of all the containers is full, no wonder Google in the 2.2 version of the Fill_parent name changed to Match_parent.

in both cases, you must deal with these limits absolutely. In some cases, it may return dimensions that exceed these limits, in which case you can have the parent element choose how to treat the out-of-view, crop, or scrolling techniques.
  
The following framework code gives a typical implementation of the view measurement:

Java code:

  1. @Override
  2. protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {
  3. int measuredheight = Measureheight (Heightmeasurespec);
  4. int measuredwidth = Measurewidth (Widthmeasurespec);
  5. Setmeasureddimension (Measuredheight, measuredwidth);
  6. }
  7. private int measureheight (int measurespec) {
  8. int specmode = Measurespec.getmode (Measurespec);
  9. int specsize = measurespec.getsize (Measurespec);
  10. The Default size if no limits is specified.
  11. int result = 500;
  12. if (Specmode = = Measurespec.at_most) {
  13. Calculate the ideal size of your
  14. Control within this maximum size.
  15. If your control fills the available
  16. Space return the outer bound.
  17. result = Specsize;
  18. }
  19. else if (Specmode = = measurespec.exactly) {
  20. If your control can fit within these bounds return that value.
  21. result = Specsize;
  22. }
  23. return result;
  24. }
  25. private int measurewidth (int measurespec) {
  26. int specmode = Measurespec.getmode (Measurespec);
  27. int specsize = measurespec.getsize (Measurespec);
  28. The Default size if no limits is specified.
  29. int result = 500;
  30. if (Specmode = = Measurespec.at_most) {
  31. Calculate the ideal size of your control
  32. Within this maximum size.
  33. If your control fills the available space
  34. Return the outer bound.
  35. result = Specsize;
  36. }
  37. else if (Specmode = = measurespec.exactly) {
  38. If your control can fit within these bounds return that value.
  39. result = Specsize;
  40. }
  41. return result;
  42. }
Copy Code


a measurespec encapsulates the layout requirements that a parent layout passes to a child layout, and each measurespec represents a set of requirements for width and height. A measurespec is made up of size and pattern. It has three modes: UNSPECIFIED (unspecified), the parent element imposes any constraint on the element, the child element can get any desired size; exactly (full), the parent element determines the exact size of the element, and the child element is limited to the given boundary and ignores its size; at_most (at most), the child element reaches a value of at most the specified size.

It is used by three functions:
1.static int getmode (int measurespec): Extract mode according to the measured value (format) provided (one of the three modes above)
2.static int getsize (int measurespec): Extracts the size value according to the measured value (format) provided (this size is what we usually call size)
3.static int makemeasurespec (int size,int mode): Creates a measure value (format) based on the provided size value and mode

The use of this class, usually called in the Onmeasure method of the view component, but with a few exceptions, take a look at a few examples:

A. First a useful function that we commonly use, view.resolvesize (int size,int measurespec)

  1. public static int resolvesize (int size, int measurespec) {
  2. int result = size;
  3. int specmode = Measurespec.getmode (Measurespec);
  4. int specsize = measurespec.getsize (Measurespec);
  5. Switch (specmode) {
  6. Case Measurespec.unspecified:
  7. result = size;
  8. Break
  9. Case Measurespec.at_most:
  10. result = Math.min (size, specsize);
  11. Break
  12. Case measurespec.exactly:
  13. result = Specsize;
  14. Break
  15. }
  16. return result;
  17. }
Copy Code


Since the Measurespec value is used, it naturally means that the function is usually called in the Onmeasure method. To put it simply, the main function of this method is to return the size value you want based on the size and pattern you provide, which is handled according to the different incoming patterns.
  
Then look at the Measurespec.makemeasurespec method, which is actually quite simple:

    1. public static int Makemeasurespec (int size, int mode) {
    2. return size + mode;
    3. }
Copy Code


It is not difficult for everyone to understand that size differs from MEASURESPEC. See how it's Used, Listview.measureitem (View child)

  1. private void MeasureItem (View child) {
  2. Viewgroup.layoutparams p = child.getlayoutparams ();
  3. if (p = = null) {
  4. p = new Viewgroup.layoutparams (
  5. ViewGroup.LayoutParams.MATCH_PARENT,
  6. ViewGroup.LayoutParams.WRAP_CONTENT);
  7. }
  8. int childwidthspec = Viewgroup.getchildmeasurespec (Mwidthmeasurespec,
  9. Mlistpadding.left + mlistpadding.right, p.width);
  10. int lpheight = P.height;
  11. int childheightspec;
  12. if (Lpheight > 0) {
  13. Childheightspec = Measurespec.makemeasurespec (Lpheight, measurespec.exactly);
  14. } else {
  15. Childheightspec = Measurespec.makemeasurespec (0, measurespec.unspecified);
  16. }
  17. Child.measure (Childwidthspec, Childheightspec);
  18. }
Copy Code


The Measurespec method is usually used in viewgroup, which can adjust the size of the child elements according to the pattern (three inside the Measurespec).
  
Note that using exactly and at_most is usually the same effect, if you want to distinguish them, then you will use the above function view.resolvesize (int size,int measurespec) to return a size value, Then use your view to call the Setmeasureddimension (int,int) function.

    1. Protected final void setmeasureddimension (int measuredwidth, int measuredheight) {
    2. Mmeasuredwidth = Measuredwidth;
    3. Mmeasuredheight = Measuredheight;
    4. Mprivateflags |= Measured_dimension_set;
    5. }
Copy Code


then you call View.getmeasuredwidth,view.getmeasuredheigth to return the value of the mmeasuredwidth,mmeasuredheight in the above function.

mode A total of three cases, the value is Measurespec.unspecified, measurespec.exactly, Measurespec.at_most.

measurespec.exactly is a precise size when we specify a control's Layout_width or Layout_height as a specific value, such as andorid:layout_width= "50dip", or Fill_ Parent yes, both are controls
the size has been determined by the exact size of the case.

Measurespec.at_most is the maximum size, and when the control's layout_width or layout_height is specified as wrap_content, the size of the control generally changes as the control's subspace or contents change, and the size of the control
as long as you do not exceed the maximum allowable size of the parent control. Therefore, mode at this point is at_most,size gives the maximum size allowed by the parent control.

measurespec.unspecified is not a specified size, this is not a lot, it is generally the parent control is Adapterview, passed through the measure method of the mode.


Original link:Http://www.apkbus.com/android-120965-1-1.html

The View.onmeasure method of Android

Related Article

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.