View working principle (4) view layout Process

Source: Internet
Author: User

Just now, I want to start a new year and wish myself a smooth sailing in the new year. At the same time, I wish all my friends a new year and a great harvest!
I. Overview of the layout process of the view in android
Layout
The view layout process is from
 
 
For more information, see http://blog.csdn.net/ff20081528/article/details/17784911、layout.
Source code of the layout () method in View (the ViewGroup class inherits the View class, and the layout process starts with the ViewGroup subclass ):
 /**     * Assign a size and position to a view and all of its     * descendants     *     * <p>This is the second phase of the layout mechanism.     * (The first is measuring). In this phase, each parent calls     * layout on all of its children to position them.     * This is typically done using the child measurements     * that were stored in the measure pass().     *     * Derived classes with children should override     * onLayout. In that method, they should     * call layout on each of their their children.     *     * @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;    }

 

A) First, let's look at the definition of this method and use the keyword final.

B) Call

C) Call

D) Clear

The source code of the setFrame method mentioned above is as follows:

protected boolean setFrame(int left, int top, int right, int bottom) {        boolean changed = false;        if (DBG) {            Log.d("View", this + " View.setFrame(" + left + "," + top + ","                    + right + "," + bottom + ")");        }        if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {            changed = true;            // Remember our drawn bit            int drawn = mPrivateFlags & DRAWN;            // Invalidate our old position            invalidate();            int oldWidth = mRight - mLeft;            int oldHeight = mBottom - mTop;            mLeft = left;            mTop = top;            mRight = right;            mBottom = bottom;            mPrivateFlags |= HAS_BOUNDS;            int newWidth = right - left;            int newHeight = bottom - top;            if (newWidth != oldWidth || newHeight != oldHeight) {                onSizeChanged(newWidth, newHeight, oldWidth, oldHeight);            }            if ((mViewFlags & VISIBILITY_MASK) == VISIBLE) {                // If we are visible, force the DRAWN bit to on so that                // this invalidate will go through (at least to our parent).                // This is because someone may have invalidated this view                // before this call to setFrame came in, therby clearing                // the DRAWN bit.                mPrivateFlags |= DRAWN;                invalidate();            }            // Reset drawn bit to original value (invalidate turns it off)            mPrivateFlags |= drawn;            mBackgroundSizeChanged = true;        }        return changed;    }
The onLayout () method in View is as follows:
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {    }

The onLayout () method in ViewGroup is as follows:

@Override    protected abstract void onLayout(boolean changed,            int l, int t, int r, int b);

 

Reprint please explain the source: http://blog.csdn.net/ff20081528/article/details/17784911

Because the onLayout () method in ViewGroup is an abstract method, we use the onLayout () method in its subclass LinearLayout for analysis. The source code is as follows:

Onlayout () method:

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

LayoutVertical () method source code:

void layoutVertical() {        final int paddingLeft = mPaddingLeft;        int childTop = mPaddingTop;        int childLeft;        // Where right end of child should go        final int width = mRight - mLeft;        int childRight = width - mPaddingRight;        // Space available for child        int childSpace = width - paddingLeft - mPaddingRight;        final int count = getVirtualChildCount();        final int majorGravity = mGravity & Gravity.VERTICAL_GRAVITY_MASK;        final int minorGravity = mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;        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) {                childTop += measureNullChild(i);            } else if (child.getVisibility() != GONE) {                final int childWidth = child.getMeasuredWidth();                final int childHeight = child.getMeasuredHeight();                final LinearLayout.LayoutParams lp =                        (LinearLayout.LayoutParams) child.getLayoutParams();                int gravity = lp.gravity;                if (gravity < 0) {                    gravity = minorGravity;                }                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);            }        }    }
A) The subview in LinearLayout has two la S: vertical and horizontal. Here we analyze them vertically.
B) obtain the width of the subview.
C) Determine the starting position of the Child view based on the grarity attribute in the parent view.
D) Start the for () loop and assign a location for each subview. For each sub-view, the LayoutParams attribute of the sub-view is obtained first and the gravity value is obtained. Determine the starting position of the horizontal direction based on the gravity value. The three values are LEFT, CENTER_HORIZONTAL, and RIGHT. call setChildFrame (). The method actually calls child. layout () sets the layout position for the subview.


Reprint please explain the source: http://blog.csdn.net/ff20081528/article/details/17784911

 

 

 


 

 
 
 

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.