前言
上一次我們講到了最基本的android運行流程和繪制流程的調(diào)用順序,我們最終得到一個結(jié)論是activity的生命周期是由系統(tǒng)服務(wù)所觸發(fā),由系統(tǒng)服務(wù)所發(fā)起handle調(diào)用到handleResumeActivity()開始繪制流程,最后交由給ViewRootImpl調(diào)用到performTraversals(),然后依次進行了我們UI的實際繪制流程measure(測量)、layout(布局?jǐn)[放)、Draw(具體繪制),那么今天我們需要了解的是對UI具體的繪制流程measrue、layout、Draw進行深入分析,并且依托于今天所學(xué)的內(nèi)容完成自定義瀑布流式布局。
View的測量流程
首先我們找到繪制流程當(dāng)中的performTraversals()的測量布局方法:

performMeasure方法:

在這里我們可以看到當(dāng)前他調(diào)用了view當(dāng)中的測量,
那么這里我們先對測量方法中的參數(shù)進行分析,
在調(diào)用performMeasure調(diào)用之前需要兩個參數(shù):
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
他這里的意思是,傳入寬高的測量規(guī)格,那么這個規(guī)格是什么意思?
進入到getRootMeasureSpec方法:

這里我們看到了一個對象MeasureSpec,
MeasureSpec的作用是在Measure流程中,系統(tǒng)將View的layoutParams根據(jù)父容器所施加的規(guī)則轉(zhuǎn)換成對應(yīng)的MeasureSpec(規(guī)格),
然后在onMeasure中根據(jù)這個MeasureSpec來確定view的測量寬高,
MeasureSpec規(guī)定了設(shè)置寬高的幾種模式:EXACTLY(match_parent)/ATMOST(wrap_content)/UNSPECIFIED,
MeasureSpec定義了一種數(shù)據(jù)結(jié)構(gòu)(32位二進制),前兩位是代表模式,后30位是size大小。
總結(jié):整體的測量流程:在performTraversals開始獲得DecorView中的系統(tǒng)布局的尺寸,然后在performMeasure方法中開始測量流程,對于不同的layout布局有著不同的實現(xiàn)方式,但大體上是在onMeasure方法中,對每一個子View進行遍歷,根據(jù)ViewGroup的MeasreuSpec及子View的layoutParams來確定自身的測量寬高,然后最后根據(jù)所有子View的測量寬高信息,再確定爸爸的寬高,不斷遍歷子View的measure方法,根據(jù)ViewGroup的MeasureSpec及子View的LayoutParams來決定子View的MeasureSpec,進一步獲取子View的測量寬高,然后逐層返回,不斷保存ViewGroup的測量寬高。