Android View measure (2) related to the custom UI control measure, androidmeasure
This article simulates three roles: Android architect-Xiao Fu, Android control development engineer-Xiao, Android Development Engineer-Xiao Bai. The following describes the measure process from different angles of the three roles.
Xiao Fu is responsible for sharing:
- The essence of measure
- Measure code process
- OnMeasure method and MeasureSpec
- Raise Questions
Xiao Hei is responsible for sharing:
- Overwrite the Measure example in layout control development-OK
- Starting from an exception
- When do I need to override onMeaure? -OK
- Difference between view. getWidth and view. getMeasureWidth-OK
Android control development engineer-share with Tom
1. overwrite the Measure example in layout control development. For details, refer to the previous example "Overwrite onMeaure to perform the measure operation". The layout frameloout, LinearLayout, and RelativeLayout provided by Android are subclasses of ViewGroup, you can refer to the onMeausre implementation of these classes to see how the Android framework handles them.
2. Starting from an exception, if return is used in onMeasure, setMeasuredDimension (width, height) is not performed. For similar operations, the following exception occurs:
java.lang.IllegalStateException: onMeasure() did not set the measured dimension by calling setMeasuredDimension()
-To be filled-
Measure method provided by ViewGroupMeasureChildren ()-This function uses for () to call measureChild () cyclically to perform the measure operation on each sub-view. measureChildWidthMargins ()-to perform the measure operation on each sub-View () -The only difference between this function and measureChild is that in measure, margin and padding are also considered as part of the size of the subview.
3. When do I need to override onMeaure? As long as it is a custom control and it is a ViewGroup, onMeasure must be overwritten to specify its measurement View Size rules, however, the classes provided by Androd, such as frameloout, LinearLayout, and RelativeLayout, are subclasses of ViewGroup and all override the onMeasure method. to customize the layout, You can first consider starting with the subclasses of these classes, it may be simpler.
Iv. view. getWidth () and view. the difference between getMeasuredWidth () and getMeasuredWidth () indicates that both methods are used to obtain the width and the corresponding method to obtain the height. But the question is, what is the difference between the two methods? The following describes the differences between these values from the source code.
First, let's take a look at the getMeasuredWidth method in View. java. The source code is as follows:
Public class View implements Drawable. callback, Drawable. callback2, KeyEvent. callback, AccessibilityEventSource {/*** Like {@ link # getMeasuredWidthAndState ()}, but only returns the * raw width component (that is the result is masked by * {@ link # MEASURED_SIZE_MASK }). ** @ return The raw measured width of this view. */public final int getMeasuredWidth () {// The mMeasuredWidth and the latter are directly returned and other switches are cleared to obtain the true measure size. return mMeasuredWidth & MEASURED_SIZE_MASK ;} /*** <p> This mehod must be called by {@ link # onMeasure (int, int)} to store the * measured width and measured height. failing to do so will trigger an * exception at measurement time. </p> ** @ param measuredWidth The measured width of this view. may be a complex * bit mask as defined by {@ link # MEASURED_SIZE_MASK} and * {@ link # MEASURED_STATE_TOO_SMALL }. * @ param measuredHeight The measured height of this view. may be a complex * bit mask as defined by {@ link # MEASURED_SIZE_MASK} and * {@ link # MEASURED_STATE_TOO_SMALL }. */protected final void trim (int measuredWidth, int measuredHeight) {// It is usually called in onMeasure to pass in the width and height of the measured view mMeasuredWidth = measuredWidth; mMeasuredHeight = measuredHeight; mPrivateFlags | = MEASURED_DIMENSION_SET;}/*** Bits of {@ link # getMeasuredWidthAndState ()} and * {@ link # getMeasuredWidthAndState ()} that provide the actual measured size. * // Mode in MeasureSpec or the first few public static final int MEASURED_SIZE_MASK = 0x00ffffff ;}
The preceding two methods show that the value of getMeasuredWidth is obtained from the mMeasuredWidth variable, which is only in View. the setMeasuredDimension method continues initialization. From the comments of the setMeasuredDimension method, we can see that this method is called in onMeasure, that is, if getMeasuredWidth obtains the size of the view in the onMeasure method of the view, the value can be assigned. GetMeasuredWidth obtains the measured value through onMeasure. It can be called before onMeasure is executed, but all obtained values are 0 (default initialization value of int type ).
The preceding figure shows the meaning of the getMeasuredWidth value. Next, let's look at the source code of the View. getWidth method:
Public class View implements Drawable. callback, Drawable. callback2, KeyEvent. callback, AccessibilityEventSource {/*** Return the width of the your view. ** @ return The width of your view, in pixels. * // @ ViewDebug. exportedProperty (category = "layout") public final int getWidth () {// right of the view minus the value on the left: return mRight-mLeft ;} /*** Assign a size and position to this view. ** This is called from layout. ** @ Param left Left position, relative to parent * @ param top Top position, relative to parent * @ param right Right right position, relative to parent * @ param bottom Bottom position, relative to parent * @ return true if the new size and position are different than the * previous ones * {@ hide} */protected boolean setFrame (int left, int top, int right, int bottom) {boolean changed = false ;....../ /If (mLeft! = Left | mRight! = Right | mTop! = Top | mBottom! = Bottom) {changed = true ;...... mLeft = left; mTop = top; mRight = right; mBottom = bottom ;......} return changed;} public void layout (int l, int t, int r, int B ){...... // execute the current view layout. input the upper and lower left boundary values of the current view boolean changed = setFrame (l, t, r, B); if (changed | (mPrivateFlags & LAYOUT_REQUIRED) = LAYOUT_REQUIRED ){...... // onLayout (changed, l, t, r, B) will be triggered after the preceding execution is complete );......}...... mPrivat EFlags & = ~ FORCE_LAYOUT ;}}
From the code above, we can see that when the view layout operation is performed, the setFrame method will be called to pass in the left, top, right, and bottom values. The layout analysis will be explained in detail in the future, these values are the positions and sizes that the parent View sets for the current view (right-left and top-bottom ). The getWidth method returns the actual screen size of the current view.
In a summary, getMeasuredWidth is the width specified by onMeasure in the view (it can be understood in general as the size of the View content area. Although not rigorous, the layout controls provided by the system are like this, in a custom view, layout_width can be ignored only because onMeasure can be overwritten, and layout_heigh can be set to its width and height at Will). getWidth is the area that the current view can display on the screen specified by the parent view.