Drawing process for Android view (bottom)--view layout and draw process

Source: Internet
Author: User

Overview

In the previous article, the drawing process of the Android view (top)--view The measure process of the view is described in detail. For the entire process of drawing the view, after measuring the size of the view, you start to determine the location of the view and draw it to the screen. The layout and draw process of the view. So take a look at how these two processes are implemented.

the layout process of the view

The drawing flow of view mentioned above starts with the Performtraversals method of Viewroot, then calls the PerformLayout in the Performtraversals method after the view completes the measurement. The following line of code can be found in performlayout.

host.layout(00, host.getMeasuredWidth(),host.getMeasuredHeight())

In this line of code the host refers to Decorview, for this decorview we all know that it is a inherit from Framelayout ViewGroup. This layout method is also the layout method in ViewGroup. Here's a look at the layout method in ViewGroup.

@Override Public Final void Layout(intLintTintRintb) {if(!msuppresslayout && (mtransition = =NULL|| !mtransition.ischanginglayout ())) {if(Mtransition! =NULL) {Mtransition.layoutchange ( This); }Super. layout (l, T, R, b); }Else{//Record The fact that we noop ' d it; Request layout when transition finishesmlayoutcalledwhilesuppressed =true; }}

From the layout method of ViewGroup we can see that it is a final type, that is, the layout method in ViewGroup is not overridden by the quilt class. The layout method in ViewGroup calls the layout method of the parent class, which is the layout method of the view. Here's a look at the layout method of the view.

@SuppressWarnings({"Unchecked"}) 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;BooleanChanged = 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);    ......    } ......}

For Setopticalframe, the Setframe method is essentially called, and the role of Setframe is to save the location of the view to the Mleft,mtop,mbottom,mright variable respectively. After that, the OnLayout method is called if the layout needs to be re-laid out.
In fact, in the view layout process, the layout method of the view is to determine the location of the view, and in the OnLayout method of the view is to determine the location of the view child elements. So here you can see that the onlayout for the view is an empty method that doesn't do anything.

protectedvoidonLayout(booleanintintintint bottom) {}

The OnLayout method of ViewGroup is an abstract method, which accomplishes the layout process of the child elements through the concrete ViewGroup implementation class.

@OverrideprotectedabstractvoidonLayout(booleanintintintint b);

Below still through a specific viewgroup, look at the Framelayout OnLayout method implementation process, for Framelayout OnLayout method implementation is very simple, so take framelayout as an example to illustrate. Here's a look at Framelayout's OnLayout method.

@OverrideprotectedvoidonLayout(booleanintintintint bottom) {    false/* no force left gravity */);}

In Framelayout's OnLayout method, only the Layoutchildren method is called, and the function of the method name is to lay out the child elements of the framelayout. Here's a look at the Layoutchildren method.

voidLayoutchildren (intLeftintTopintRightintBottomBooleanforceleftgravity) {Final intCount = Getchildcount ();Final intParentleft = Getpaddingleftwithforeground ();Final intParentright = Right-left-getpaddingrightwithforeground ();Final intParenttop = Getpaddingtopwithforeground ();Final intParentbottom = Bottom-top-getpaddingbottomwithforeground (); for(inti =0; I < count; i++) {FinalView child = Getchildat (i);if(Child.getvisibility ()! = GONE) {FinalLayoutparams LP = (layoutparams) child.getlayoutparams ();Final intwidth = Child.getmeasuredwidth ();Final intHeight = child.getmeasuredheight ();intChildleft;intChildtop;intGravity = lp.gravity;if(Gravity = =-1) {gravity = default_child_gravity; }Final intLayoutDirection = Getlayoutdirection ();Final intabsolutegravity = Gravity.getabsolutegravity (Gravity, layoutdirection);Final intverticalgravity = Gravity & gravity.vertical_gravity_mask;Switch(Absolutegravity & Gravity.horizontal_gravity_mask) { CaseGravity.CENTER_HORIZONTAL:childLeft = Parentleft + (parentright-parentleft-width)/2+ Lp.leftmargin-lp.rightmargin; Break; CaseGravity.right:if(!forceleftgravity) {childleft = Parentright-width-lp.rightmargin; Break; } CaseGravity.left:default: Childleft = Parentleft + lp.leftmargin; }Switch(verticalgravity) { CaseGravity.TOP:childTop = Parenttop + lp.topmargin; Break; CaseGravity.CENTER_VERTICAL:childTop = Parenttop + (parentbottom-parenttop-height)/2+ Lp.topmargin-lp.bottommargin; Break; CaseGravity.BOTTOM:childTop = Parentbottom-height-lp.bottommargin; Break;default: Childtop = parenttop + lp.topmargin;        } child.layout (Childleft, childtop, Childleft + width, childtop + height); }    }}

The logic for this piece of code is also simple. By traversing all the child elements within the framelayout, and then obtaining the width and height of the view measurement, the position of the child view in the parent control is determined based on the gravity property of the child view (four vertices). Finally, the layout method of the child view is called to complete the entire measurement process of the view.

the draw process for view

After the entire layout of the view tree has been completed through the Viewroot Performtraversals method, the view is drawn to the phone screen. The draw process for view is done by calling the Performdraw method in the Viewroot Performtraversals method. In the Performdraw method, you will end up drawing the view by creating a canvas object and invoking the view's draw method.

@CallSuper 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;/* * Draw Traversal performs several drawing steps which must be executed * in the appropriate order: * * 1. Draw the background * 2. If necessary, save the canvas ' layers to prepare for fading * 3. Draw View ' s content * 4. Draw Children * 5. If necessary, draw the fading edges and restore layers * 6. Draw Decorations (scrollbars for instance) */    //Step 1, draw the background, if needed    intSavecount;if(!dirtyopaque)    {drawbackground (canvas); }//Skip Step 2 & 5 if possible (common case)    Final intViewFlags = Mviewflags;BooleanHorizontaledges = (ViewFlags & fading_edge_horizontal)! =0;BooleanVerticaledges = (ViewFlags & fading_edge_vertical)! =0;if(!verticaledges &&!horizontaledges) {//Step 3, draw the content        if(!dirtyopaque) OnDraw (canvas);//Step 4, Draw the childrenDispatchdraw (canvas);//Overlay is part of the content and draws beneath Foreground        if(Moverlay! =NULL&&!moverlay.isempty ()) {Moverlay.getoverlayview (). Dispatchdraw (canvas); }//Step 6, Draw decorations (foreground, scrollbars)Ondrawforeground (canvas);//we ' re done ...        return; }   ......}

The draw process is analyzed here from the macro. In the comments, you can see that the drawing process for view is divided into six steps. The second and fifth steps are generally seldom used and can be ignored. The remaining steps are:

    1. Draw background drawbackground (canvas)
    2. Draw self OnDraw (canvas)
    3. Draw children Dispatchdraw (canvas)
    4. Drawing decorative ondrawforeground (canvas)

      For the child view of the drawing pass through Dispatchdraw, the Dispatchdraw method in view is implemented by ViewGroup, and the draw method that calls all child elements is traversed to complete the entire view tree drawing process.

Summary

The drawing process for view is divided into three major strides. It is the measurement, layout and drawing of the view, respectively. First, the View tree node is manipulated by Viewroot. Traverse down in turn to complete their measure,layout,draw process. So that the view is displayed on the phone screen.

Drawing process for Android view (bottom)--view layout and draw process

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.