measure的開始
- View的measure是由ViewRoot的實現(xiàn)類ViewRootImpl,調(diào)用performTraversals(執(zhí)行遍歷)方法開始的,再通過performMeasure方法調(diào)用頂級View
-
ActivityThread創(chuàng)建Activity以及獲取WindowManagerGlobal實例,并將ViewRootImpl和DecorView建立關(guān)聯(lián),下圖是根據(jù)源碼列出的關(guān)鍵類
ViewRootImpl與DecorView關(guān)聯(lián)
MeasureSpec測量規(guī)格
- 頂級View就是DecorView,MeasureSpec是由窗口尺寸和自身LayoutParams共同確定
- 普通View的MeasureSpec是由父容器的MeasureSpec和自身LayoutParams共同確定
- MeasureSpec測量規(guī)格
由低30位表示SpecSize和高2位表示SpecMode組成,系統(tǒng)提供makeMeasureSpec方法進行組合
UNSPECIFIED 沒有任何限制
EXACTLY 精準(zhǔn)模式
AT_MOST 最大模式
普通View的MeasureSpec
- 子View大小明確時,都是精準(zhǔn)模式
- 父View大小不明確時,除子View明確外,都是最大模式
ViewGroup測量
- 有兩種操作measureChildWithMargins和measureChild
- measureChildWithMargins
ViewGroup本身不調(diào)用,需要繼承類重載generateDefaultLayoutParams方法,返回ViewGroup.MarginLayoutParams布局實例,由繼承類通過for循環(huán)調(diào)用此方法進行子View的測量,除了測量額外計算margin值外與measureChild基本一致,可以再LinearLayout等類中查看
-
measureChild
遍歷調(diào)用所有子View的measure方法
再measureChild方法中通過getChildMeasureSpec方法獲取子View的MeasureSpec
ViewGroup測量
child.measure方法直接將MeasureSpec傳遞給View的方法萊測量
ViewGroup是一個抽象類,測量過程onMeasure方法再繼承的子類中實現(xiàn),比如LinearLayout、RelativeLayout的onMeasure方法等
View的測量
-
調(diào)用的方法如圖
View測量 - onMeasure中setMeasuredDimension方法設(shè)置View寬高的測量值
- getDefaultSize就是獲取View的大小,精準(zhǔn)模式和最大模式返回的就是父View傳遞的measureSpec,就是測量模式和剩余空間大小
- UNSPECIFIED模式根據(jù)getSuggestedMinimumWidth方法獲取
View沒有背景值,就是android:minWidth值,默認0
View有背景,背景的最小值和最小寬度值兩者的最大值
- 由getDefaultSize可知,當(dāng)模式位最大模式時,返回的值大小位剩余空間,也就是match_parent效果,如果還需要包裹內(nèi)容,就要重寫onMeasure方法,類似如下方法設(shè)置實際的寬度值
if(widthSpecMode == MeasureSpec.AT_MOST){
setMeasuredDmension(mWidth, heightSpecSize);
}


