Android View System (eight) parsing view's layout and draw process 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 source code
Android View System (vii) measure process for resolving view from source code

Preface

In the previous article we talked about the measure process of view. Next we'll talk about the layout and draw flow of the view, assuming you understand the measure process of the view. Then this article is a natural one.

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 that are passed in are the coordinates of the four points of the view. Its coordinates are not relative to the original point of the screen, and are relative to its parent layout.

L and T are the distance between the left and top edges of the child control relative to the left and top edges of the parent class 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 position is determined by different implementations 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 very easy. 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); }   }

From the gaze of the source code we see a draw process with six steps. The steps 2nd and 5th can be skipped:

    1. Suppose there is a setting background. Then draw the background
    2. Save Canvas Layer
    3. Draw your own content
    4. If you have child elements, draw child elements
    5. Drawing effect
    6. Painting Decorations (scrollbars)

Well, the workflow for view is here, and then we'll talk about defining view.

Android View System (eight) parsing view's layout and draw process 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.