MEASUREMENT PROCESS OF View AND View GROUP

Keywords: Android Java

MEASUREMENT PROCESS OF View AND View GROUP

Views have three main processes, measurement, layout, draw, i.e. measurement, layout and drawing. Let's first analyze the first process measure.

1. Measurement process of View

View measurement process is completed by its measure(), which is final type, that is, can not be overridden, colleague measure() will transfer onMeasure(), so we can focus on onMeasure() for the time being. In fact, when we customize a view control, we also override onMeasure method.
  1. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  2. setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
  3. getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
  4. }
The above method is to call setMeasuredDismension() to set mMeasuredWidth and mMeasuredHeight. These two variables will be used in the layout and draw ing processes of View. But when setMeasuredDismension is called, its parameters are obtained by getDefaultSize(). The source code is as follows:
  1. public static int getDefaultSize(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. case MeasureSpec.EXACTLY:
  11. result = specSize;
  12. break;
  13. }
  14. return result;
  15. }
  16. protected int getSuggestedMinimumWidth() {
  17. return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
  18. }
Where getDefaultSize is based on View's MesureSpec and another parameter size to get the return value.
Among them, we need to pay attention to the two modes of MeasureSpec.AT_MOST and MesureSpec. EXACTLY, that is, both return specSize. This specSize is the size of getsize called by MesureSpec of View generated by MesureSpec of parent container and LayoutParams of View itself, which can be understood as View. The width and height obtained after measurement.
Another pattern above MeasureSpec.UNSPECIFIED is used for internal measurement of the system. In this case, the return value is size, that is, the return value of getSuggested MinimumWidth and getSuggested MinimumHeight.
From the getSuggested MinimumWidth () source code, you can conclude that if View has no background, View Width is the value of android:minWidth. If this value is not set, it is 0. If the background is set, it is the larger value of the width of android:minWidth and background icon.

2. Measurement process of ViewGroup

Since measure cannot be overridden and ViewGroup does not override onMeasure(), this measurement process is handled in other ways. In fact, measureChildren() is used.
ViewGroup.java
  1. protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {
  2. final int size = mChildrenCount;
  3. final View[] children = mChildren;
  4. for (int i = 0; i < size; ++i) {
  5. final View child = children[i];
  6. if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {//Visible
  7. measureChild(child, widthMeasureSpec, heightMeasureSpec);
  8. }
  9. }
  10. }
  11. protected void measureChild(View child, int parentWidthMeasureSpec,
  12. int parentHeightMeasureSpec) {
  13. final LayoutParams lp = child.getLayoutParams();
  14. final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
  15. mPaddingLeft + mPaddingRight, lp.width);
  16. final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
  17. mPaddingTop + mPaddingBottom, lp.height);
  18. child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
  19. }

The above code calls the measure() method of child view iteratively, and if child view has children, the measureChildren() will be executed recursively.
Where getChildMeasureSpec() has previously noted "View" MeasureSpec and LayoutParams Relations have been analyzed in this article, and we will repeat the analysis here.
So we can know that ViewGroup does not perform a specific measurement process, but only calls the measure() method of child view. This is because there are too many ViewGroup and so on, which is not easy to handle uniformly. In fact, it is all kinds of things to rewrite onMeasure from their own processing.


Posted by watthehell on Wed, 27 Mar 2019 03:18:30 -0700