Detailed explanation of layout process in Android (combined with the latest Android 4.0.4 source code)

Source: Internet
Author: User
Tags call back

Similar to the onMeasure process, ViewGroup calls its children's layout function in the onLayout function to set the position of the child view relative to the parent view. The specific position is determined by the parameter of the function layout, when we inherit ViewGroup, We must reload the onLayout function (onLayout in ViewGroup is abstract modifier). However, onMeasure does not require reload, because compared with layout, the measure process is not necessary, the details will be mentioned later. First, let's look at the source code of layout and onLayout functions in View. java:
[Java]
Public void layout (int l, int t, int r, int B ){
Int oldL = mLeft;
Int oldT = mTop;
Int oldB = mBottom;
Int oldR = mRight;
Boolean changed = setFrame (l, t, r, B );
If (changed | (mPrivateFlags & LAYOUT_REQUIRED) = LAYOUT_REQUIRED ){
If (ViewDebug. TRACE_HIERARCHY ){
ViewDebug. trace (this, ViewDebug. HierarchyTraceType. ON_LAYOUT );
}
 
OnLayout (changed, l, t, r, B );
MPrivateFlags & = ~ LAYOUT_REQUIRED;
 
ListenerInfo li = mListenerInfo;
If (li! = Null & li. mOnLayoutChangeListeners! = Null ){
ArrayList <OnLayoutChangeListener> listenersCopy =
(ArrayList <OnLayoutChangeListener>) li. mOnLayoutChangeListeners. clone ();
Int numListeners = listenersCopy. size ();
For (int I = 0; I <numListeners; ++ I ){
ListenersCopy. get (I). onLayoutChange (this, l, t, r, B, oldL, oldT, oldR, oldB );
}
}
}
MPrivateFlags & = ~ FORCE_LAYOUT;
}
The main process of the function layout is still easy to understand. First, assign values to the four member variables (mLeft, mTop, mRight, mBottom) by calling the setFrame function, and then call back the onLayout function, finally, the onLayoutChange function of all registered listener is called back.
For the View, onLayout is just an empty implementation. In general, we do not need to reload this function:
[Java]
Protected void onLayout (boolean changed, int left, int top, int right, int bottom ){
}
Next let's take a look at the source code of layout in ViewGroup. java:
[Java]
Public final void layout (int l, int t, int r, int B ){
If (mTransition = null |! MTransition. isChangingLayout ()){
Super. layout (l, t, r, B );
} Else {
// Record the fact that we noop 'd it; request layout when transition finishes
Mlayoutsuppsuppressed = true;
}
}
Super. layout (l, t, r, B) calls View. in java, the layout function adds LayoutTransition processing to ViewGroup. LayoutTransition is used to process the animation effect of adding and deleting subviews to and from ViewGroup. That is to say, if LayoutTransition animation is not added to the current ViewGroup, or the LayoutTransition animation is not running at the moment, so super is called. layout (l, t, r, B) is called to onLayout in ViewGroup. Otherwise, set mlayoutsuppsuppressed to true and call requestLayout () when the animation is completed ().
The above super. layout (l, t, r, B) will be called to onLayout in ViewGroup. java. The source code implementation is as follows:
[Java] view plaincopy
@ Override
Protected abstract void onLayout (boolean changed,
Int l, int t, int r, int B );
And the previous View. compared to the onLayout implementation in java, the only difference is that the ViewGroup has the abstract modification keyword. That is to say, the ViewGroup class can only be used for inheritance and cannot be instantiated, and its subclass must overload the onLayout function, the purpose of reloading onLayout is to arrange the children's location in the parent view. To overload onLayout, we usually initiate a for loop to call the layout (l, t, r, and B) function of each sub-view, and input different parameters l, t, r, B To determine the display position of each subview in the parent view.
How can we determine the four parameters l, t, r, and B in layout (l, t, r, and B? Considering the previous measure process, the final result of the measure process is to determine the mMeasuredWidth and mMeasuredHeight of each view. These two parameters can be simply understood as the width and height that the view expects to display on the screen, these two parameters provide an important basis for the layout process (but not necessary). To illustrate this process, let's look at the layout process of LinearLayout:


[Java]
Void layoutVertical (){
......
For (int I = 0; I <count; I ++ ){
Final View child = getVirtualChildAt (I );
If (child = null ){
ChildTop + = measureNullChild (I );
} Else if (child. getVisibility ()! = GONE ){
Final int childWidth = child. getMeasuredWidth ();
Final int childHeight = child. getMeasuredHeight ();
......
SetChildFrame (child, childLeft, childTop + getLocationOffset (child ),
ChildWidth, childHeight );
ChildTop + = childHeight + lp. bottomMargin + getNextLocationOffset (child );
 
I + = getChildrenSkipCount (child, I );
}
}
}
Private void setChildFrame (View child, int left, int top, int width, int height ){
Child. layout (left, top, left + width, top + height );
}
From setChildFrame, we can see that the right boundary of the subview in LinearLayout is left + width, and the bottom boundary is top + height. That is to say, the width and height of the subview in LinearLayout are determined by the measure process, therefore, the measure process provides reference values of the View display range for the layout process.
Does the layout process depend on the mMeasuredWidth and mMeasuredHeight calculated by measure to determine the display size of the view? This is not the case. The four parameters l, t, r, and B in the layout process can be specified by the view designer at will, the layout position and size of the final view are completely determined by the four parameters. The mMeasuredWidth and mMeasuredHeight values obtained in the measurement process provide the View Size values, but we can skip these two values, the measure process is not mandatory. \\
The difference between the getWidth (), getHeight (), getMeasuredWidth (), and getMeasuredHeight () functions is mentioned here. getMeasuredWidth (), getMeasuredHeight () the returned values are mMeasuredWidth and mMeasuredHeight obtained by the measure process, while getWidth () and getHeight () return values of mRight-mLeft and mBottom-mTop. the source code in java is clear:
[Java]
Public final int getMeasuredWidth (){
Return mMeasuredWidth & MEASURED_SIZE_MASK;
}
Public final int getWidth (){
Return mRight-mLeft;
}
This also explains why getWidth (), getMeasuredWidth (), getHeight (), and getMeasuredHeight () get different values in some cases.

Conclusion: The entire layout process is easy to understand. Generally, the layout process will arrange the position of the child view displayed in the parent view based on the mMeasuredWidth and mMeasuredHeight calculated during the measure process, however, this is not necessary. The results obtained by the measure process may be of no practical use. Especially for custom viewgroups, the number, position, and size of their subviews are fixed, in this case, we can ignore the entire measure process and arrange the specific position of each sub-view only with the four parameters passed in the layout function.

 

Author: zjmdp

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.