Android View System (eight) analyze the layout and draw process of view from source code

Source: Internet
Author: User

Related articles
Android View System (i) Views coordinate system
Android View System (ii) six ways to implement view swipe
Android View System (iii) property animation
Android View System (iv) parsing from source code scroller
Android View System (v) the event distribution mechanism for resolving view from source code
Android View System (vi) parsing the composition of activity from the source code
Android View System (vii) The measure process for interpreting view from source code

Preface

In the previous article we talked about the measure process of view, and then we'll talk about the layout and draw process of view, and if you understand the measure process of view, this article will be a cinch.

layout process for 1.View

First look at the layout () method of view:

  Public void Layout(intLintTintRintb) {if((MPRIVATEFLAGS3 & pflag3_measure_needed_before_layout)! =0) {onmeasure (Moldwidthmeasurespec, Moldheightmeasurespec);        MPRIVATEFLAGS3 &= ~pflag3_measure_needed_before_layout; }intOLDL = Mleft;intOldt = Mtop;intOldb = Mbottom;intOldr = Mright;                Boolean changed = Islayoutmodeoptical (mparent)? Setopticalframe (L, T, R, B): Setframe (L, T, R, b);if(Changed | |            (Mprivateflags & pflag_layout_required) = = pflag_layout_required) {onlayout (changed, L, T, R, b);            Mprivateflags &= ~pflag_layout_required; Listenerinfo li = mlistenerinfo;if(Li! =NULL&& Li.monlayoutchangelisteners! =NULL) {arraylist<onlayoutchangelistener> listenerscopy = (arraylist<onlayoutch angelistener>) Li.mOnLayoutChangeListeners.clone ();intNumlisteners = Listenerscopy.size (); for(inti =0; i < numlisteners; ++i) {listenerscopy.Get(i). Onlayoutchange ( This, L, T, R, B, Oldl, Oldt, Oldr, OLDB);        }}} mprivateflags &= ~pflag_force_layout;    MPRIVATEFLAGS3 |= pflag3_is_laid_out; }

The four parameters are the coordinates of the four points of the view, the coordinates of which are not relative to the origin of the screen, and relative to its parent layout. L and T are the distance between the left and top edges of the child controls relative to the left and top edges of the parent control;
R and B are the distance between the right and bottom edges of the child controls relative to the left and top edges of the parent class control. Take a look at what the Setframe () method says:

    protected Boolean Setframe(intLeftintTopintRightintBottom) {BooleanChanged =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            intDrawn = Mprivateflags & pflag_drawn;intOldWidth = Mright-mleft;intOldHeight = Mbottom-mtop;intNewwidth = Right-left;intNewheight = Bottom-top;BooleansizeChanged = (newwidth! = oldwidth) | | (Newheight! = oldheight);//Invalidate our old positionInvalidate (sizeChanged);            Mleft = left;            Mtop = top;            Mright = right;            Mbottom = bottom;        Mrendernode.setlefttoprightbottom (Mleft, Mtop, Mright, Mbottom); ... OmittedreturnChanged }

The Setframe () method is used primarily to set the values of the four vertices of the view, that is, the values of Mleft, Mtop, Mright, and Mbottom. After calling the Setframe () method, call the OnLayout () method:

  protectedvoidonLayout(booleanintintintint bottom) {    }

The OnLayout () method does not do anything, this is similar to the Onmeasure () method, where the location is determined differently depending on the control, so the OnLayout () method is not implemented in both view and ViewGroup. In that case, let's take a look at LinearLayout's OnLayout () method:

  @Override    protectedvoidonLayout(booleanintintintint b) {        if (mOrientation == VERTICAL) {            layoutVertical(l, t, r, b);        else {            layoutHorizontal(l, t, r, b);        }    }

What did layoutvertical do?

 voidLayoutvertical (intLeftintTopintRightintBottom) {Final intPaddingleft = Mpaddingleft;intChildtop;intChildleft;//Where right end of the child should go        Final intwidth = right-left;intChildright = Width-mpaddingright;//Space available for child        intChildspace = Width-paddingleft-mpaddingright;Final int Count= Getvirtualchildcount ();Final intmajorgravity = mgravity & gravity.vertical_gravity_mask;Final intminorgravity = mgravity & gravity.relative_horizontal_gravity_mask;Switch(majorgravity) { CaseGravity.bottom://Mtotallength contains the padding alreadyChildtop = Mpaddingtop + bottom-top-mtotallength; Break;//Mtotallength contains the padding already            CaseGravity.CENTER_VERTICAL:childTop = Mpaddingtop + (bottom-top-mtotallength)/2; Break; CaseGravity.top:default: Childtop = mpaddingtop; Break; } for(inti =0; I <Count; i++) {FinalView child = Getvirtualchildat (i);if(Child = =NULL) {Childtop + = Measurenullchild (i); }Else if(Child.getvisibility ()! = GONE) {Final intChildwidth = Child.getmeasuredwidth ();Final intChildheight = Child.getmeasuredheight ();FinalLinearlayout.layoutparams LP = (linearlayout.layoutparams) child.getlayoutparams ();intGravity = lp.gravity;if(Gravity <0) {gravity = minorgravity; }Final intLayoutDirection = Getlayoutdirection ();Final intabsolutegravity = Gravity.getabsolutegravity (Gravity, layoutdirection);Switch(Absolutegravity & Gravity.horizontal_gravity_mask) { CaseGravity.CENTER_HORIZONTAL:childLeft = Paddingleft + ((childspace-childwidth)/2) + Lp.leftmargin-lp.rightmargin; Break; CaseGravity.RIGHT:childLeft = Childright-childwidth-lp.rightmargin; Break; CaseGravity.left:default: Childleft = paddingleft + lp.leftmargin; Break; }if(Hasdividerbeforechildat (i))                {childtop + = Mdividerheight;                } childtop + = Lp.topmargin;                Setchildframe (Child, Childleft, Childtop + getlocationoffset (child), Childwidth, childheight);                Childtop + = childheight + Lp.bottommargin + getnextlocationoffset (child);            i + = Getchildrenskipcount (child, I); }        }    }

This method iterates through the child elements and calls the Setchildframe () method:

  privatevoidsetChildFrameintintintint height) {                child.layout(left, top, left + width, top + height);    }

Call the layout () method of the child element in the Setchildframe () method to determine its position. We see childtop this value is gradually increasing, this is to in the vertical direction, the child elements are arranged one by one instead of overlapping.

draw process for 2.View

The draw process for view is simple, first look at the draw () method of view:

  Public void Draw(Canvas canvas) {Final intPrivateflags = Mprivateflags;Final BooleanDirtyopaque = (Privateflags & pflag_dirty_mask) = = Pflag_dirty_opaque && (Mattachinfo = =NULL||        !mattachinfo.mignoredirtystate); Mprivateflags = (privateflags & ~pflag_dirty_mask) | Pflag_drawn;//Step 1, draw the background, if needed        intSavecount;if(!dirtyopaque)        {drawbackground (canvas); }... Omitted//Step 2, Save the canvas ' layers        intPaddingleft = Mpaddingleft;Final Booleanoffsetrequired = ispaddingoffsetrequired ();if(offsetrequired)        {paddingleft + = Getleftpaddingoffset (); }... Omitted//Step 3, draw the content        if(!dirtyopaque) OnDraw (canvas);//Step 4, Draw the childrenDispatchdraw (canvas); Omitted//Step 5, draw the fade effect and restore layers        FinalPaint p = scrollabilitycache.paint;FinalMatrix matrix = Scrollabilitycache.matrix;FinalShader fade = Scrollabilitycache.shader; Omitted//Step 6, Draw decorations (scrollbars)Ondrawscrollbars (canvas);if(Moverlay! =NULL&&!moverlay.isempty ()) {Moverlay.getoverlayview (). Dispatchdraw (canvas); }   }

Note from the source code we see the draw process has six steps:

    1. If background is set, the background is drawn
    2. Save Canvas Layer
    3. Draw your own content
    4. Draw child elements
    5. Drawing effect
    6. Painting Decorations (scrollbars)

Well, here's the workflow for view, and then we'll talk about custom view.

Android View System (eight) analyze the layout and draw process of view from source code

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.