View's measure mechanism and Viewmeasure Mechanism

Source: Internet
Author: User

View's measure mechanism and Viewmeasure Mechanism

In Android, the View framework has three main processes:

1. measurement mechanism of the View tree Android View framework
2. layout of the View tree Android View framework
3. draw Mechanism of the Android View framework for drawing the View tree

The workflow of the View framework is to measure the size of each View (measure) --> place each View to the corresponding location (layout) --> draw each View (draw ).

1. Why is there a measure process in the system?

When drawing the UI, developers usually configure the UI through the XML layout file. The two group attributes that each View must set are layout_width and layout_height, these two attributes represent the size of the current View.

Official documentation:

Therefore, the values of these two attributes must be specified. The values of these two attributes can only be of three types:

1. fixed size, such as 100dp.

2. The content is wrapped in wrap_content.

3. match_parent/fill_parent, which is as big as the parent layout.

Because Android wants to provide a more elegant GUI framework, it provides adaptive dimensions, that is, wrap_content and match_parent.

Imagine that if these attributes only allow a fixed size, the size of each View will be determined during painting, so the measurement process may not be required. However, a measurement process is required to meet the adaptive size mechanism.

2. What did the measure process do?

Because of the adaptive size mechanism mentioned above, the actual size of the View cannot be determined when the adaptive size is used to define the View size. However, the View size needs to be mapped to the pixel size on the screen. Therefore, the measurement process is to do this. Various size values are calculated to obtain specific pixel values. The measure process traverses the entire View tree and then measures the actual size of each View in sequence. Specifically, each ViewGroup sends the measure command to each sub-View within it, and then the onMeasure () of the specific sub-View is used to measure its size. The final measurement result is stored in the mMeasuredWidth and mMeasuredHeight of the View. The unit of the stored data is pixel.

3. How can we reasonably measure a View tree based on the adaptive size mechanism?

After traversing the layout file, the system generates the corresponding View tree structure in the memory for the layout file. At this time, no specific size is available for all View objects of the entire View tree, because the measure process is ultimately to determine the exact size of each View, that is, the accurate pixel value. However, at the beginning, the values of layout_width and layout_height attributes in the View were both adaptive dimensions, that is, match_parent and wrap_content. These two values were negative in the system, therefore, the system does not regard them as specific size values. Therefore, when a View needs to convert its match_parent or wrap_content to a specific pixel value, it needs to know two pieces of information.

 1. For match_parent, the actual pixel value of the parent layout is as large as that of the parent layout.

2. For wrap_content, the Child View needs to calculate a reasonable minimum value that can wrap all content based on its internal content. However, if the minimum value is greater than the current parent layout, no. The parent layout will tell you that I am only so large that you should not exceed this size.

Due to the particularity of the data structure such as tree, we can only study the simple scenarios of one ViewGroup and two views when studying the measure process. Probably as follows:

That is to say, in the measure process, ViewGroup performs a comprehensive evaluation based on its current situation and the size data of the Child View, and then tells the child View the relevant information, then, when the child View is onMeasure, the restriction information of the parent layout needs to be considered while taking into account the content size of the Child View. Then, a comprehensive evaluation is made to measure an optimal result.

4. How does the ViewGroup transmit the restriction information to the subview?

When it comes to transfer the restriction information, it is the MeasureSpec class, which runs through the entire measure process and is used to transmit the constraint information of the parent layout for the size measurement of the Child View. In short, this class stores two types of data.
1. The size of the parent layout of the Child View.
2. The parent layout specifies the type of the Child View.
There are three types of restrictions:
1. UNSPECIFIED, not limited. That is to say, I can give you the size of the sub-View if you want it. You can safely measure it without worrying about anything else. You don't have to worry about the size that I pass to you. (In fact, It is recommended in the Android high version. If this mode is used, the size is set to 0)
2. EXACTLY, accurate. This means that, based on my current situation and your specified size parameters, you should consider this size. The specific size is in the measurement spec's size attribute. Check it by yourself, you don't need to worry about the size of your content. Use this size.
3. AT_MOST, the most. This means that, based on my current situation and the size parameters you specified, we can consider that, without exceeding the size limit, you can just measure the size that fits your content.

Source code analysis

The following information about the measure process is extracted from the View source code.

We know that the root node of the entire View tree is DecorView, which is a FrameLayout, so it is a ViewGroup, therefore, the measurement of the entire View tree starts from the measure Method of a ViewGroup object.

View:
1. measure

/** Start to measure the size of a View. The parent will provide the constraint information in the parameter. The actual measurement is carried out in onMeasure (). This method will call onMeasure () method, so only onMeasure can be and must be override */
Public final void measure (int widthMeasureSpec, int heightMeasureSpec );

The parent layout calls child. measure in its onMeasure method, which transfers the measure process to the child View.

2. onMeasure

/** The specific measurement process, measurement view and its content determine the measurement width and height (mMeasuredWidth mMeasuredHeight ). In this method, you must call setMeasuredDimension (int, int) to save the width and height of the view measurement. */

Protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec );

In this method, the Child View will reasonably measure its size based on the restriction information given by the parent layout and its own content size.

3. setMeasuredDimension

/** Save measurement results */

Protected final void setMeasuredDimension (int measuredWidth, int measuredHeight );

After the View measurement is complete, save the measurement results in mMeasuredWidth and mMeasuredHeight.

ViewGroup: 1. measureChildren

/** To allow all sub-views to measure their own sizes, consider the current ViewGroup's MeasureSpec and Padding. Skip the child view in gone status */
Protected void measureChildren (int widthMeasureSpec, int heightMeasureSpec); --> getChildMeasureSpec () --> child. measure ();

Measure the size of all sub-views and submit the measurement process to the sub-View.

2. measureChild

/** To measure a single View, consider the current ViewGroup's MeasureSpec and Padding. */
Protected void measureChild (View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec); --> getChildMeasureSpec () --> child. measure ();

Measure each specific sub-View.

 

3. measureChildWithMargins

/** To measure a single View, consider the current ViewGroup's MeasureSpec, Padding, and margins. */
Protected void measureChildWithMargins (View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed); --> getChildMeasureSpec () --> child. measure ();

Measure each specific sub-View. However, information such as margin must be taken into account.

4. getChildMeasureSpec

/** The most difficult part of the measureChildren process is to calculate the MeasureSpec for the child. This method calculates the correct MeasureSpec for each dimension (width and height) of each child. The goal is to combine the current viewgroup's MeasureSpec with child's LayoutParams to generate the most reasonable results. For example, the current ViewGroup knows its exact size, because the mode of MeasureSpec is EXACTLY, and the child wants to be able to match_parent, then an EXACTLY mode is generated for child, measureSpec of ViewGroup size. */

Public static int getChildMeasureSpec (int spec, int padding, int childDimension );

Based on the current situation and the size parameters of the stator View, a reasonable restriction information is calculated for the stator View.

Source code:

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.