日韩性视频-久久久蜜桃-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过程的全部內容,希望文章能夠幫你解決所遇到的問題。

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

    主站蜘蛛池模板: 一区二区伦理片 | 午夜久久影院 | 中字幕视频在线永久在线观看免费 | 欧美色视频在线 | 成人a视频在线观看 | 精品在线视频一区二区三区 | 日韩人妻无码一区二区三区 | 性欧美18一19性猛交 | 三级三级久久三级久久 | 777片理伦片在线观看 | 亚洲黄色一级大片 | 爱情岛论坛自拍亚洲品质极速最新章 | 亚洲人交配视频 | 视频一区二区三区在线 | 国产 一二三四五六 | 亚洲AV无码一区二区伊人久久 | 亚洲欧美另类日韩 | 日韩av麻豆| 国产精品久久久久99 | 性一交一乱一伧老太 | 色呦呦麻豆 | 黄色视屏网站 | 亚洲av毛片成人精品 | 爱爱高潮视频 | 一级黄色片a | 精品福利一区二区 | 久久av秘一区二区三区 | 日韩精品一区二区三区在线视频 | 欧美色图11p | 男女国产视频 | 男女天堂av | 麻豆传媒在线看 | 国产成人一级 | 中国人妖和人妖做爰 | 天堂网在线观看 | 尤物精品在线观看 | 自拍偷拍第一页 | 日韩有码在线视频 | 国产91精品久久久 | 国产三级a| 草免费视频 | 中文字幕久久熟女蜜桃 | 无码精品视频一区二区三区 | 激情五月综合色婷婷一区二区 | 欧美一区二区三区婷婷 | 91国在线 | 久久久久色 | 亚洲我射| 成人动漫在线免费观看 | 日韩黄色在线视频 | 99超碰在线观看 | 欧美日韩国产精品一区 | 亚洲色欧美| 欧美熟妇精品久久久久久 | 香港三级网站 | 欧美老肥妇做爰bbww | 伊人涩涩 | 亚洲无人区码一码二码三码 | 91在线视频| 激情二区 | 久久日韩精品 | 蜜桃av噜噜 | 干干日日 | 一区二区在线观看免费 | 啪啪的网站 | 国产网友自拍视频 | 欧美日韩亚洲二区 | 色多多在线看 | 光棍影院av | 黑人巨大国产9丨视频 | 国产一区二区三区四区 | 国产精品扒开做爽爽爽的视频 | 奇米综合 | 免费午夜网站 | a毛片成人 | 国产欧美熟妇另类久久久 | gv天堂gv无码男同在线观看 | 国产成人精品亚洲男人的天堂 | 可以在线看黄的网站 | 你懂的在线免费观看 | 三上悠亚在线播放 | 午夜在线小视频 | 亚洲熟妇一区 | 日韩欧美卡一卡二 | 毛片视频播放 | 亚洲三级国产 | 欧美日韩中文字幕在线视频 | 午夜福利一区二区三区 | 欧美大片大全 | 久久夜色精品国产欧美乱极品 | 爽妇网国产精品 | 96日本xxxxxⅹxxx17 | 不卡日本视频 | 美女张开腿流出白浆 | 又黄又爽视频 | 91精品国产高清 | 久久婷婷影视 | 日韩一区二区三区电影 | 免费又黄又爽又色的视频 |