Android onMeasure、Measure、measureChild、measureChildren 一些簡要說明

在View.Java中的定義:

public final void measure(int widthMeasureSpec,int heightMeasureSpec){
...
onMeasure
...
}

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
public static int getDefaultSize(int size, int measureSpec) {  
      int result = size;  
      int specMode = MeasureSpec.getMode(measureSpec);  
      int specSize = MeasureSpec.getSize(measureSpec);  
  
      switch (specMode) {  
      case MeasureSpec.UNSPECIFIED: //未指定  
          result = size;  
          break;  
      case MeasureSpec.AT_MOST: //至多  
      case MeasureSpec.EXACTLY: //精確  
          result = specSize;  
          break;  
      }  
      return result;  
  }  
在ViewGroup中:
protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {  
     final int size = mChildrenCount;  
     final View[] children = mChildren;  
     for (int i = 0; i < size; ++i) {  
         final View child = children[i];  
         if ((child.mViewFlags & VISIBILITY_MASK) != GONE) {  
             measureChild(child, widthMeasureSpec, heightMeasureSpec);  
         }  
     }  
 }  
protected void measureChild(View child, int parentWidthMeasureSpec,  
         int parentHeightMeasureSpec) {  
     final LayoutParams lp = child.getLayoutParams();  
  
     final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,  
             mPaddingLeft + mPaddingRight, lp.width);  
     final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,  
             mPaddingTop + mPaddingBottom, lp.height);  
  
     child.measure(childWidthMeasureSpec, childHeightMeasureSpec);  
 }  
protected void measureChildWithMargins(View child,  
           int parentWidthMeasureSpec, int widthUsed,  
           int parentHeightMeasureSpec, int heightUsed) {  
       final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();  
  
       final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,  
               mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin  
                       + widthUsed, lp.width);  
       final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,  
               mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin  
                       + heightUsed, lp.height);  
  
       child.measure(childWidthMeasureSpec, childHeightMeasureSpec);  
   }  

說明:

  1. measure是final修飾的方法,不可被重寫。
    在外部調(diào)用時,直接調(diào)用view.measure(int wSpec, int hSpec)。
    measure中調(diào)用了onMeasure。
    自定義view時,重寫onMeasure即可。

2.MeasureSpec 這是一個含mode和size的結(jié)合體,不需要我們來具體的關(guān)心。
當(dāng)在測量時,可以調(diào)用MeasureSpec.getSize|getMode 得到相應(yīng)的size和mode。
然后使用MeasureSpec.makeMeasureSpec(size,mode); 來創(chuàng)建MeasureSpec對象。
那么mode是怎么來的呢?是根據(jù)使用該自定義view時的layoutWith|height參數(shù)決定的,所以不能自己隨便new一個。
而size可以自己指定,也可以直接使用 measureSpec.getSize。

3.如果是一個View,重寫onMeasure時要注意:
如果在使用自定義view時,用了wrap_content。那么在onMeasure中就要調(diào)用setMeasuredDimension,
來指定view的寬高。如果使用的fill_parent或者一個具體的dp值。那么直接使用super.onMeasure即可。

4.如果是一個ViewGroup,重寫onMeasure時要注意:
首先,結(jié)合上面兩條,來測量自身的寬高。
然后,需要測量子View的寬高。
測量子view的方式有:
getChildAt(int index).可以拿到index上的子view。
通過getChildCount得到子view的數(shù)目,再循環(huán)遍歷出子view。
接著,subView.measure(int wSpec, int hSpec); //使用子view自身的測量方法
或者調(diào)用viewGroup的測量子view的方法:
//某一個子view,多寬,多高, 內(nèi)部加上了viewGroup的padding值
measureChild(subView, int wSpec, int hSpec);
//所有子view 都是 多寬,多高, 內(nèi)部調(diào)用了measureChild方法
measureChildren(int wSpec, int hSpec);
//某一個子view,多寬,多高, 內(nèi)部加上了viewGroup的padding值、margin值和傳入的寬高wUsed、hUsed
measureChildWithMargins(subView, intwSpec, int wUsed, int hSpec, int hUsed);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容