日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

View工作原理(四)view的layout过程

發布時間:2025/6/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 View工作原理(四)view的layout过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
剛過完自己的本命年,新的一年希望自己有個新的開始,祝自己在新的一年里一帆風順,同時也祝廣大的朋友們新年新氣象,收獲多多!
一、android中view的layout過程總概
Layout過程其實就是父視圖按照子視圖的大小及布局參數將子視圖放在窗口的合適的位置上。 視圖的布局過程是從ViewRoot對象調調用根視圖的layout()方法開始,接著layout()方法調用根視圖的onLayout()方法,onLayout()方法會對所包含的子視圖逐一執行layout操作,如果子視圖是ViewGroup子類對象,則繼續調用子視圖的layout(),重復這一過程。如果子視圖是View子類對象,則在子視圖重載的onLayout()內部只需要將自己布局到視圖中,不需要對子視圖進行layout操作,這樣一次layout過程結束。過程如下圖: ?
轉載請說明出處:http://blog.csdn.net/ff20081528/article/details/17784911
二、layout詳細過程
View中的layout()方法源碼(ViewGroup類繼承了View類,layout過程先從ViewGroup子類開始): [java] view plaincopy
  • /**?
  • ????*?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)?首先我們看這個方法的定義,用了關鍵字final,說明此方法是不可被重寫的,這樣也就保證了Viewlayout過程是不變的。四個參數看注釋,左、上、右、下分別相距父視圖的距離。

    b)?調用setFrame(l,t,r,b)將位置保存起來,這些參數將保存到View內部變量?(mLeftmTopmRightmBottom)中。保存完變量前,會先對比這些參數是否和原來的相同,如果相同,則什么都不做,如果不同則進行重新賦值,并在賦值前給mPrivateFlags中添加DRAWN標識,同時調用invalidate()通知View系統原來占用的位置需要重繪。

    c)?調用onLayout(),View中定義的onLayout()方法默認什么都不做,View系統提供onLayout()方法的目的是為了使系統包含的子視圖的父視圖能夠在onLayout()方法對子視圖進行位置分配,正因為如此,如果是父視圖,則必須重寫onLayout(),也正因為如此ViewGroup類才會把onLayout重載改成了abstract類型。

    d)清除mPrivateFlags中的LAYOUT_REQUIRED標識,因為layout操作已經完成。

    上面提到的setFrame方法源碼如下:

    [java] view plaincopy
  • 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;??
  • ????}??
  • ?View中的onLayout()方法如下: [java] view plaincopy
  • protected?void?onLayout(boolean?changed,?int?left,?int?top,?int?right,?int?bottom)?{??
  • ????}??
  • 而ViewGroup中的onLayout()方法如下:

    [java] view plaincopy
  • @Override??
  • ????protected?abstract?void?onLayout(boolean?changed,??
  • ????????????int?l,?int?t,?int?r,?int?b);??
  • ?

    轉載請說明出處:http://blog.csdn.net/ff20081528/article/details/17784911?

    因為ViewGroup中的onLayout()方法是一個抽象方法,所以下面我們用他的子類LinearLayout中的onLayout()方法來分析。源碼如下:

    onlayout()方法:

    [java] view plaincopy
  • @Override??
  • ???protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{??
  • ???????if?(mOrientation?==?VERTICAL)?{??
  • ???????????layoutVertical();??
  • ???????}?else?{??
  • ???????????layoutHorizontal();??
  • ???????}??
  • ???}??
  • layoutVertical()方法源碼:

    [java] view plaincopy
  • 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)?LinearLayout中的子視圖有兩種布局方式,一個是縱向的,一個是橫向的,這里我們以縱向的分析。 b)?獲得子視圖的寬度。 c)?根據父視圖中的grarity屬性,來判斷子視圖的起始位置。 d) 開始for()循環,為每個子視圖分配位置。對于每個子視圖首先取出子視圖的LayoutParams屬性,并且獲得gravity的值。根據gravity的值確定水平方向的起始位置,三種值分別為:LEFT,CENTER_HORIZONTAL和RIGHT.接著調用setChildFrame(),該方法內部實際上就是調用child.layout()為子視圖設置布局位置。 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的View工作原理(四)view的layout过程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 中文字幕第页 | 在线观看9.1 | 最新av网站在线观看 | 免费av成人| 亚洲一区二区三区四区在线观看 | 桃色激情网| 美女扒开腿让男人捅 | 91免费影片 | 日韩中文字幕网站 | 欧美系列在线观看 | 福利视频在线看 | 福利电影在线播放 | 欧美自拍第一页 | 欧美一级在线免费 | 欧美偷拍精品 | 影音先锋亚洲资源 | 国产精品免费观看视频 | 日韩精品欧美精品 | 亚洲av无码乱码在线观看性色 | 日本激情免费 | 日本色婷婷| 亚洲av成人无码一二三在线观看 | 91成品人影院 | 亚洲午夜久久久久 | 精品人妻一区二区三区三区四区 | 一曲二曲三曲在线观看中文字幕动漫 | jzzijzzij亚洲成熟少妇 | 亚洲区免费 | 国产成人亚洲精品无码h在线 | 老司机深夜网站 | 国产欧美一区二区三区白浆喷水 | 欧美日韩在线国产 | 五月99久久婷婷国产综合亚洲 | 久久五月天av | 亚洲综合在线视频 | 日日夜夜天天 | 96国产精品 | sm久久捆绑调教精品一区 | 日本三级大片 | 婷综合| 日韩欧美在线免费观看 | 中国女人真人一级毛片 | 色婷在线| 正在播放国产精品 | 夜夜嗨av一区二区三区四区 | 日韩亚州 | 亚洲乱色熟女一区二区 | 亚洲图片在线播放 | 巨乳美女被爆操 | 性欧美video另类hd尤物 | 丰满少妇xoxoxo视频 | 一进一出视频 | 成人观看| 欧美成人一区二区三区片免费 | 日日摸日日添日日碰9学生露脸 | 成人小说亚洲一区二区三区 | 午夜鲁鲁 | 伊人开心网 | 欧美伦理一区 | 在线日韩中文字幕 | 日韩视频一区二区三区在线播放免费观看 | 日日操日日干 | jizz毛片| 香蕉福利视频 | 成人免费毛片足控 | 深夜激情网站 | 久久二区三区 | 99精品影视| 热热色av| 4438成人网 | youjizzxxxxx | 在线观看国产日韩 | 男生舔女生胸 | 久九九 | 中文字幕精品在线视频 | 成人免费在线 | 色婷婷在线影院 | 第四色影音先锋 | 欧美性大战xxxxx久久久 | 青青草原成人网 | 欧美特黄一级视频 | 亚洲精品国产精品国 | 亚洲av网址在线 | 黄色片免费网站 | 久久久久免费观看 | 精品在线小视频 | 五月婷婷爱 | 久久精品5| xxxxxxxx黄色片| 成 人 黄 色 片 在线播放 | www.4虎 | 国产精品扒开腿做爽爽 | 97色伦97色伦国产欧美空 | 午夜视频在线观看一区 | 久九九| 91手机视频在线观看 | 精品国偷自产一区二区三区 | 日韩欧美三级在线观看 | h在线播放 |