Source code analysis of the View rendering mechanism in Android 3. androidview

Source: Internet
Author: User

Source code analysis of the View rendering mechanism in Android 3. androidview

So far, the measure process has been explained, and we will start learning the layout process today. But before learning the layout process, have you found that I changed the editor? haha, finally, I made up my mind to switch from the Html editor to the markdown editor. Here I use the word "resolution" because after all, the Html editor has been used for several years and many habits have been developed, it is indeed difficult to change the habits of many years. I believe this is why many people insist on using the Html editor. This also reflects a phenomenon. When people are very familiar with something, once new things want to replace old things, people will have a conflict, people who work in technology are also the same. When they are very familiar with a certain technology and new similar technologies come out, they all have resistance, this is why some people on the Internet always discuss the quality of various programming languages. At the same time, you will find a problem. When you are very familiar with a certain technology, if you have a great deal of work to complete a task using the technology you are familiar with, while using another new technology is very easy to implement, I believe most of them will choose the technical implementation you are familiar, even if his workload is very heavy. Like the html editor and markdown Editor, markdown is much more powerful than the html editor in terms of typographical layout, but many others are reluctant to switch over. But what I want to talk about today is actually as a programmer. If there are new technologies in our field, we should spend time researching on the premise that we have the energy, at least there should be no resistance. Well, let's get down here today ....
Now let's start learning the layout process of ViewGroup. If you have not learned any of my previous articles, read the previous two articles first.
Source code analysis of the View rendering mechanism in Android
Source code analysis of View rendering mechanism in Android 2
Like the measure method, the layout method is also called from the javasmtraversals method of the ViewRoot class. The Code is as follows:

 final boolean didLayout = mLayoutRequested;        boolean triggerGlobalLayoutListener = didLayout                || attachInfo.mRecomputeGlobalAttributes;        if (didLayout) {            mLayoutRequested = false;            mScrollMayChange = true;            if (DEBUG_ORIENTATION || DEBUG_LAYOUT) Log.v(                "ViewRoot", "Laying out " + host + " to (" +                host.mMeasuredWidth + ", " + host.mMeasuredHeight + ")");            long startTime = 0L;            if (Config.DEBUG && ViewDebug.profileLayout) {                startTime = SystemClock.elapsedRealtime();            }            host.layout(0, 0, host.mMeasuredWidth, host.mMeasuredHeight);            if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {                if (!host.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_LAYOUT)) {                    throw new IllegalStateException("The view hierarchy is an inconsistent state,"                            + "please refer to the logs with the tag "                            + ViewDebug.CONSISTENCY_LOG_TAG + " for more infomation.");                }            }

We found that the host is called. layout (0, 0, host. mMeasureWidth, host. mMeasureHeight), as mentioned in the previous article, host is DecorView, host. mMeasuredWidth and host. after performing the measure process, mMeasureHeight is the width and height of the host, that is, the width and height of the screen. The layout method is a method in the View. Let's take a look at the layout code first.

    /**     *     * @param l Left position, relative to parent     * @param t Top position, relative to parent     * @param r Right position, relative to parent     * @param b Bottom position, relative to parent     */    public final void layout(int l, int t, int r, int b) {        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;        }        mPrivateFlags &= ~FORCE_LAYOUT;    }

Like measure, layout is a final method, so subclass cannot change its behavior. in layout, the onLayout method is called to complete the actual logic, however, not every time the laout method calls the onLayout method, the setFrame method is called to save the top, bottom, and left positions respectively, in addition, the setFrame method determines whether the position is the same as that of the previous top, bottom, left, and right. If it is not saved differently, true is returned. Otherwise, false is returned directly. the onLayout method is called only when the value of true or LAYOUT_REQUIRED is returned. The onLayout method must be implemented by the subclass (ViewGroup) based on its own situation. Therefore, when you customize ViewGroup, onLayout needs to be rewritten frequently. In onLayout, we can place the Layout View in the ViewGroup according to our own needs. The four parameter comments of layout have been clearly written, representing the position of the left, top, right, and bottom of the View in the parent View respectively, we can know that the host is full on the screen. To have a deeper understanding of layout, I will use LinearLayout to explain how to use layout to allocate the positions of sub-views.

    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        if (mOrientation == VERTICAL) {            layoutVertical();        } else {            layoutHorizontal();        }    }

In the onLayout method of LinearLayout, like the onMeasure method, layoutVertical and LayoutHorizontal are called respectively based on the current LinearLayout arrangement method. Let's take a look at layoutVertical in the vertical bar.

/*** Position the children during a layout pass if the orientation of this * LinearLayout is set to {@ link # VERTICAL }. ** @ see # getOrientation () * @ see # setOrientation (int) * @ see # onLayout (boolean, int) */void layoutVertical () {// The distance from the left to the top of final int paddingLeft = mPaddingLeft; // child, which is equal to the top of pading int childTop = mPaddingTop; int childLeft; // The available width of LinearLayout final int width = MRight-mLeft; int childRight = width-mPaddingRight; // Space available for child int childSpace = width-paddingLeft-mPaddingRight; // number of sub-views final int count = getVirtualChildCount (); final int majorGravity = mGravity & Gravity. VERTICAL_GRAVITY_MASK; final int minorGravity = mGravity & Gravity. HORIZONTAL_GRAVITY_MASK; // calculate the childTop location if (majorGravity! = Gravity. TOP) {switch (majorGravity) {case Gravity. BOTTOM: // mTotalLength contains the padding already, we add the top // padding to compensate childTop = mBottom-mTop + mPaddingTop-mTotalLength; break; case Gravity. CENTER_VERTICAL: childTop + = (mBottom-mTop)-mTotalLength)/2; break ;}for (int I = 0; I <count; I ++) {final View child = getVirtualChildAt (I); if (child = null) {ch IldTop + = measureNullChild (I);} else if (child. getVisibility ()! = GONE) {final int childWidth = child. getMeasuredWidth (); final int childHeight = child. getMeasuredHeight (); // get the LayoutParams final LinearLayout of the sub-View. layoutParams lp = (LinearLayout. layoutParams) child. getLayoutParams (); int gravity = lp. gravity; if (gravity <0) {gravity = minorGravity;} // calculate the childLeft switch (gravity & Gravity. HORIZONTAL_GRAVITY_MASK) {case Gravity. LEFT: childLeft = paddingLeft + lp. leftMargin; break; case Gravity. CENTER_HORIZONTAL: childLeft = paddingLeft + (childSpace-childWidth)/2) + lp. leftMargin-lp. rightMargin; break; case Gravity. RIGHT: childLeft = childRight-childWidth-lp. rightMargin; break; default: childLeft = paddingLeft; break;} childTop + = lp. topMargin; setChildFrame (child, childLeft, childTop + getLocationOffset (child), childWidth, childHeight); childTop + = childHeight + lp. bottomMargin + getNextLocationOffset (child); I + = getChildrenSkipCount (child, I );}}}

In fact, the logic of the layoutVertical method of LinearyLayout is very simple: Calculate the starting position of the subview in LinearLayout, that is, the childTop above. Even if the current LinearLayout is first aligned in the vertical direction:
1. If it is Gravity. BottomchildTop = mBottom - mTop + mPaddingTop - mTotalLength;This is easy to understand, so if mTotalLenght is greater than the screen height, childTop is likely to be negative, so that the top is invisible.
2. If it is Gravity. CENTER_VERTICALchildTop += ((mBottom - mTop) - mTotalLength) / 2;

3. If it is Gravity. TopchildTop = mPaddingTop;The default values correspond to the following three Alignment Methods:

After the childTop calculation is complete, the child views are traversed. childLeft is calculated based on the horizontal layout of LinearLayout. Some people may be confused here. This is the vertical layout. Why do we need to look at the horizontal layout, because the child view can be horizontally centered even in the vertical direction, different horizontal la s are different in childLeft.

If it is Gravity. LEFTchildLeft = paddingLeft + lp.leftMargin;
If it is Gravity. CENTER_HORIZONTALChildLeft = paddingLeft + (childSpace-childWidth)/2) + lp. leftMargin-lp. rightMargin;
If it is Gravity. RIGHT, then yes
ChildLeft = childRight-childWidth-lp. rightMargin ;'

Now both childTop and childLeft have been computed. Because the measurement has been performed, childBottom and childRight are easy to calculate. The setChildFrame method is called here, which is actually called child. the layout method is used to set the child layout. Now, the layout process of LinearLayout has been explained.

Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.