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