天天看點

measureChildren的工作原理

無論是在重寫view還是viewgroup的時候,尤其是viewgrop的時候,往往不可避免的重寫onmeasure方法,我們一定會調用setmeasureddimension()将測量好的寬高值傳遞進去。也不免調用measurechildren方法,來測量所有的子view的大小,下面我們看看measurechildren方法是如何工作的。這對我們重寫onmeasure無疑是很有幫助的。因為一般我們都會看到這一行代碼

但是它到底測量到什麼程度,滿足不滿足我們自定義viewgroup對下面一系列child尺寸的測量需求,不知道這個我們寫代碼就心裡沒底。是以我們有必要扒出它的老底來看看,由此來決定我們是否可以直接使用這個方法,還是由于我們有更多的效果要實作,有更多的因素需要考慮,這個方法不能滿足需求,需要自己寫方法來測量child。

同時我們在有必要重新寫方法來測量child的時候,我們也要從自帶方法的思路開始擴充。

說了一大堆,總之這個問題很重要。

下面要了解它的工作原理,我們還是要來看看源碼:

(一)首先是measurechildren

這部分很簡單,也就是周遊所有的子view,如果view的狀态不是gone就調用measurechild去進行下一步的測量。

(二)是以我們再來看一下measurechild

*/ protected void measurechild(view child, int parentwidthmeasurespec, int parentheightmeasurespec) { // 取得子視圖的布局參數 final layoutparams lp = child.getlayoutparams(); // 通過getchildmeasurespec擷取最終的寬高詳細測量值 final int childwidthmeasurespec = getchildmeasurespec(parentwidthmeasurespec,

mpaddingleft + mpaddingright, lp.width); final int childheightmeasurespec = getchildmeasurespec(parentheightmeasurespec, mpaddingtop + mpaddingbottom, lp.height); // 将計算好的寬高詳細測量值傳入measure方法,完成最後的測量 child.measure(childwidthmeasurespec, childheightmeasurespec);

}

這個方法就是對一個子視圖進行測量,其中一個重要的方法就是getchildmeasurespec(),

(三)是以我們再來看一下getchildmeasurespec

總而言之,這些判斷和設定其實就是根據三種模式以及傳入的尺寸要求,還有需要考慮的padding和margin之後,比較全面的計算出了一個測量值,了解了這些之後我們就可以确定什麼時候需要自己寫關于子視圖的測量部分,什麼時候我們隻需要簡單的一行代碼:

就可以滿足我們的需求了,是以一切還是按需來處理。

在我個人看來,這個方法考慮的比我最初想象的要全面多了,看來除了有比較特殊的需求,大部分的時候都是可以直接使用這個方法的。這還是省了不少事的。

如果您對我提到的模式或者是重寫過程不大了解的,具體的關于重寫onmeasure内容請詳見我的另外一篇部落格:

http://blog.csdn.net/sunmc1204953974/article/details/38454267

希望大家能有所收獲,我也是學生,有什麼寫的不好的地方還請多多指教!