The onlayout of 3.View drawing analysis notes

Source: Internet
Author: User

In the previous article we learned about view onmeasure, so today we continue to learn the second step of the Android View Drawing trilogy, OnLayout, layout.

Viewrootimpl#performlayout
private void PerformLayout (windowmanager.layoutparams LP, int desiredwindowwidth,
int desiredwindowheight) {
mlayoutrequested = false;
Mscrollmaychange = true;
Minlayout = true;

Final View host = MView;
if (Debug_orientation | | Debug_layout) {
LOG.V (Mtag, ' laying out ' + Host + ' to (' +
host.getmeasure Dwidth () + "," + host.getmeasuredheight () + ")");
Trace.tracebegin (Trace.trace_tag_view," Layout ");
Host.layout (0, 0, host.getmeasuredwidth (), Host.getmeasuredheight ());
//The code omitted here is in the process of layout, the repetitive requestlayout that need to be handled.
//The specific treatment scheme is to re-measure,layout.
...
Trace.traceend (Trace.trace_tag_view);

/span>

The main function of this method is to call the Host.layout, and the already well-mapped wide-height transmission calculation into the upper and lower left and right hand over, host is Decorview.

View#layout
public void layout (int l, int t, int r, int b) {
According to the MPRIVATEFLAGS3 mark bit status, if necessary, re-measure.
if ((MPRIVATEFLAGS3 & pflag3_measure_needed_before_layout)! = 0) {
Onmeasure (Moldwidthmeasurespec, Moldheightmeasurespec);
MPRIVATEFLAGS3 &= ~pflag3_measure_needed_before_layout;
}

int OLDL = Mleft;
int Oldt = Mtop;
int oldb = Mbottom;
int oldr = Mright;

Check that there is a change in position and Setframe
Setframe analysis See below
Boolean changed = Islayoutmodeoptical (mparent)?
Setopticalframe (L, T, R, B): Setframe (L, T, R, b);

OnLayout if the position is changed or if the pflag_layout_required mark bit is on
if (changed | | (Mprivateflags & pflag_layout_required) = = pflag_layout_required) {
OnLayout (changed, L, T, R, b);
Put the pflag_layout_required mark position off
Mprivateflags &= ~pflag_layout_required;

Make a Onlayoutchange callback
Listenerinfo li = mlistenerinfo;
if (Li! = null && li.monlayoutchangelisteners! = null) {
arraylist<onlayoutchangelistener> listenerscopy =
(arraylist< onlayoutchangelistener>) Li.mOnLayoutChangeListeners.clone ();
int numlisteners = Listenerscopy.size ();
Listenerscopy.get (i). Onlayoutchang E (this, L, T, R, B, Oldl, Oldt, Oldr, OLDB);

Mprivateflags &= ~pflag_ Force_layout;
MPrivateFlags3 |= pflag3_is_laid_out;

/span>
View#setframe
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 there is any change in the upper and lower left or right, continue down or return false
if (mleft! = left | | Mright! = RIGHT | | Mtop! = TOP | | Mbottom! = bottom) {
changed = TRUE;

Record the status of the Pflag_drawn, the last time you need to restore
int drawn = mprivateflags & pflag_drawn;

int oldwidth = Mright-mleft;
int oldheight = Mbottom-mtop;
int newwidth = Right-left;
int newheight = Bottom-top;
Boolean sizeChanged = (newwidth! = oldwidth) | | (Newheight! = oldheight);

Refresh the original layout, and the Invalidate method will expand in detail in another article.
Invalidate (sizeChanged);

Setting the view up or down, is also the core function of Setframe
Mleft = left;
Mtop = top;
Mright = right;
Mbottom = bottom;
Mrendernode.setlefttoprightbottom (Mleft, Mtop, Mright, Mbottom);
Pflag_has_bounds position is on
Mprivateflags |= pflag_has_bounds;

If the dimensions are changed, call Onsizechange and call Rebuildoutline
if (sizeChanged) {
Sizechange (Newwidth, Newheight, OldWidth, oldheight);
}

if (mviewflags & visibility_mask) = = VISIBLE | | mghostview = NULL) {
If We are visible, the drawn bit
This invalidate would go through (at least to our parent).
This was because someone may has invalidated this view
Before this call to Setframe came in, thereby clearing
The drawn bit.
Mprivateflags |= Pflag_drawn;
invalidate (sizeChanged);
//any child
Invalidateparentcaches ();

Mprivateflags |= drawn;
//android accessibility notice
Notifysubtreeaccessibilitystatechangedifneeded ();

/span>
Framelayout#onlayout

If it is a view, after executing the layout method, then he is finished, but if it is viewgroup, then it needs to handle its child view. The main function of OnLayout is to call Layoutchildren, and to lay out a pair of view, so here are layoutchildren.

protected void OnLayout (Boolean changed, int left, int top, int. right, int bottom) {
Layoutchildren (left, top, right, bottom, false/* No Force Left gravity */);
}

void Layoutchildren (int left, int top, int. right, int bottom, Boolean forceleftgravity) {
Final int count = Getchildcount ();

Calculates the upper and lower sides of the parent
Final int parentleft = Getpaddingleftwithforeground ();
Final int parentright = Right-left-getpaddingrightwithforeground ();

Final int parenttop = Getpaddingtopwithforeground ();
Final int parentbottom = Bottom-top-getpaddingbottomwithforeground ();

for (int i = 0; i < count; i++) {
Final View child = Getchildat (i);
if (child.getvisibility ()! = GONE) {
Final Layoutparams LP = (layoutparams) child.getlayoutparams ();

Final int width = child.getmeasuredwidth ();
Final int height = child.getmeasuredheight ();

int childleft;
int childtop;

int gravity = lp.gravity;
if (Gravity = =-1) {
Gravity = default_child_gravity;
}

Gets the layout default orientation, usually from left to right, in some specific languages, right-to-left
Final int layoutdirection = Getlayoutdirection ();
The absolute transverse position property is calculated by the direction value just above
Final int absolutegravity = gravity.getabsolutegravity (Gravity, layoutdirection);
To calculate vertical position properties
Final int verticalgravity = gravity & gravity.vertical_gravity_mask;

Calculates the left and right of a child view by using the Position property
Switch (absolutegravity & gravity.horizontal_gravity_mask) {
Case Gravity.center_horizontal:
Childleft = Parentleft + (parentright-parentleft-width)/2 +
Lp.leftmargin-lp.rightmargin;
Break
Case Gravity.right:
if (!forceleftgravity) {
Childleft = Parentright-width-lp.rightmargin;
Break
}
Case Gravity.left:
Default
Childleft = Parentleft + lp.leftmargin;
}

Calculates the top and bottom of a child view with positional properties
Switch (verticalgravity) {
Childtop = Parenttop + lp.topmargin;
Childtop = Parenttop + (Parentbottom- Parenttop-height)/2 +
Lp.topmargin-lp.bottommargin;
Childtop = Parentbottom-height-lp.bottommargin;

Child.layout (Childleft, childtop, Childleft + width, childtop + height);

/span>
Timing Diagram

Diagram of view layout sequence diagram

Summary

The layout method of view drawing is introduced here. It's a lot easier than measure,layout. But here also reserved some pits, did not explain clearly, such as invalidate, there are rendernode hardware acceleration, and later will write some notes specifically for these knowledge points to do comb.

Series Articles

Android View and view drawing analysis notes Setcontentview
Onmeasure of view Drawing analysis notes
OnLayout of view Drawing analysis notes
OnDraw of view Drawing analysis notes

The onlayout of 3.View drawing analysis notes

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.