一個MeasureSpec封裝了父佈局傳遞給子佈局的佈局要求,每一個MeasureSpec表明了一組寬度和高度的要求。一個MeasureSpec由大小和模式組成。它有三種模式:UNSPECIFIED(未指定),父元素部隊自元素施加任何束縛,子元素能夠獲得任意想要的大小;EXACTLY(徹底),父元素決定自元素的確切大小,子元素將被限定在給定的邊界裏而忽略它自己大小;AT_MOST(至多),子元素至多達到指定大小的值。java
它經常使用的三個函數:web
1.static int getMode(int measureSpec):根據提供的測量值(格式)提取模式(上述三個模式之一)函數
2.static int getSize(int measureSpec):根據提供的測量值(格式)提取大小值(這個大小也就是咱們一般所說的大小)佈局
3.static int makeMeasureSpec(int size,int mode):根據提供的大小值和模式建立一個測量值(格式)spa
這個類的使用呢,一般在view組件的onMeasure方法裏面調用但也有少數例外,看看幾個例子:code
a.首先一個咱們經常使用到的一個有用的函數,View.resolveSize(int size,int measureSpec)orm
public static int resolveSize(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: result = Math.min(size, specSize); break; case MeasureSpec.EXACTLY: result = specSize; break; } return result; }
再看看MeasureSpec.makeMeasureSpec方法,實際上這個方法很簡單:ci
public static int makeMeasureSpec( size, mode) { return size + mode; }
這樣你們不難理解size跟measureSpec區別了。看看它的使用吧,ListView.measureItem(View child)
get
private void measureItem(View child) { ViewGroup.LayoutParams p = child.getLayoutParams(); if (p == null) { p = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); } int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec, mListPadding.left + mListPadding.right, p.width); int lpHeight = p.height; int childHeightSpec; if (lpHeight > 0) { childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY); } else { childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); } child.measure(childWidthSpec, childHeightSpec); }
measureSpec方法一般在ViewGroup中用到,它能夠根據模式(MeasureSpec裏面的三個)能夠調節子元素的大小。it
注意,使用EXACTLY和AT_MOST一般是同樣的效果,若是你要區別他們,那麼你就要使用上面的函數View.resolveSize(int size,int measureSpec)返回一個size值,而後使用你的view調用setMeasuredDimension(int,int)函數。
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) { mMeasuredWidth = measuredWidth; mMeasuredHeight = measuredHeight; mPrivateFlags |= MEASURED_DIMENSION_SET; }
而後你調用view.getMeasuredWidth,view.getMeasuredHeigth 返回的就是上面函數裏的mMeasuredWidth,mMeasuredHeight的值。