MeasureSpec類
MeasureSpec類是一個32位的int值(使用位運算是爲了提高並優化效率),高2位是測量模式,低30位是測量大小。
測量模式:
EXACTLY(精確模式):
當把View設置成match_parent時或設置具體的大小時,容器傳入的即是EXACTLY模式AT_MOST(最大值模式):
源碼可以看出:final boolean isWrapContentWidth = widthMode != MeasureSpec.EXACTLY; final boolean isWrapContentHeight = heightMode != MeasureSpec.EXACTLY;
當把View設置成wrap_content時,容器傳入的是AT_MOST模式。注意的是,自定義View時,需要取出我們制定的大小和specSize中最小的一個來作最後的測量值。如果自定義View時制定了wrap_content屬性,但是沒有重寫onMeasure()方法,系統不知道該使用默認多大的尺寸,因此會默認填滿整個父佈局。
UNSPECIFIED:
不指定大小的測量模式,View想多大就多大(很少見)
onMeasure() sample:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
}
measureWidth() Sample:
private int measureWidth(int measureSpec){
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY){
result = specSize;
}else {
result = 200;
if(specMode == MeasureSpec.AT_MOST){
result = Math.min(result, specSize);
}
}
return result;
}
NOTE:
onMeasure()方法中的widthMeasureSpec和heightMeasureSpec是由父視圖經過計算後傳進來的