resolveSize(int size , int measureSpec);
這是一個(gè)自定義view獲取size的神器错妖,
首先我們來看下 我不知道這個(gè)方法之前獲取size的寫法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mStepCount = mSteps.size();
if (mStepCount == 0) {
setMeasuredDimension(0, 0);
} else {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY) {
mHeight = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
mHeight = Math.min(mCircleRadius * 2 + 8 + mTextSize, heightSize);
} else {
mHeight = heightSize;
}
int desireWidth = (mCircleRadius * mSteps.size() + mLineLength * (mSteps.size() - 1)) * 2;
if (widthMode == MeasureSpec.EXACTLY) {
if (desireWidth > widthSize) {
float v = desireWidth * 1f / widthSize;
mCircleRadius = (int) (mCircleRadius * 1f / v);
mLineLength = (int) (mLineLength * 1f / v);
}
mWidth = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
if (desireWidth > mScreenWidth) {
float v = desireWidth * 1f / mScreenWidth;
mCircleRadius = (int) (mCircleRadius * 1f / v);
mLineLength = (int) (mLineLength * 1f / v);
desireWidth = (mCircleRadius * mSteps.size() + mLineLength * (mSteps.size() - 1)) * 2;
}
mWidth = Math.min(desireWidth, widthSize);
} else {
mWidth = widthSize;
}
setMeasuredDimension(mWidth, mHeight);
}
}
整整40行,而通過這個(gè)方法后獲得的
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //對于desireSize邑时,只是我為了講解烹俗,只是臨時(shí)寫的一個(gè)初始值,大家要自己根據(jù)需要計(jì)算
int desireWidthSize = 0;
int width =resolveSize(desireWidthSize, widthMeasureSpec);
int desireHeightSize= 0;
int height = resolveSize(desireHeightSize, heightMeasureSpec);
setMeasuredDimension(width, height);
}
只要8行 有沒有很吊,有沒有很吊,很簡單望浩,縮短了整整5倍伤锚,當(dāng)然這個(gè)方法我不推薦初學(xué)者立馬就使用,而是希望初學(xué)者能夠多寫寫我寫的那種险胰,這樣子能夠更深刻的明白o(hù)nmeasure這個(gè)方法的使用汹押,以及如何實(shí)現(xiàn),
那么接下來就來說下這個(gè)方法起便,其實(shí)這方法也是挺簡單的 接受兩個(gè)參數(shù)棚贾,size,measureSpec榆综,
首先第一個(gè)參數(shù)的意思你希望你的view有多大妙痹,第二個(gè)參數(shù)的就是測量的measureSpec,
通過查看這個(gè)方法的源碼
/**
* Version of {@link #resolveSizeAndState(int, int, int)}
* returning only the {@link #MEASURED_SIZE_MASK} bits of the result.
*/
public static int resolveSize(int size, int measureSpec) {
return resolveSizeAndState(size, measureSpec, 0) & MEASURED_SIZE_MASK;
}
是這個(gè)鼻疮,然后繼續(xù)看
/**
* Utility to reconcile a desired size and state, with constraints imposed
* by a MeasureSpec. Will take the desired size, unless a different size
* is imposed by the constraints. The returned value is a compound integer,
* with the resolved size in the {@link #MEASURED_SIZE_MASK} bits and
* optionally the bit {@link #MEASURED_STATE_TOO_SMALL} set if the
* resulting size is smaller than the size the view wants to be.
*
* @param size How big the view wants to be.
* @param measureSpec Constraints imposed by the parent.
* @param childMeasuredState Size information bit mask for the view's
* children.
* @return Size information bit mask as defined by
* {@link #MEASURED_SIZE_MASK} and
* {@link #MEASURED_STATE_TOO_SMALL}.
*/
public static int resolveSizeAndState(int size, int measureSpec, int childMeasuredState) {
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec); //獲取size怯伊,mode
final int result;
switch (specMode) {
case MeasureSpec.AT_MOST://如果是AT_MOST
if (specSize < size) { //,測量出來的size<你需要的size陋守,那么他就會(huì)告訴你 測量出的來的size過小
result = specSize | MEASURED_STATE_TOO_SMALL;
} else {
result = size; //否則的話 就返回你需要的size
}
break;
case MeasureSpec.EXACTLY:
result = specSize; //對于是EXACTLY,你測出來多大 震贵,就返回多大
break;
case MeasureSpec.UNSPECIFIED:
default:
result = size; //至于是UNSPECIFIED,那就返回你需要的size
}
return result | (childMeasuredState & MEASURED_STATE_MASK);
}
耐心的仔細(xì)讀下來水评,就會(huì)發(fā)現(xiàn)猩系,其實(shí)他就是做了幫你測量步驟,具體請看我后面的注釋
google幫你寫好了步驟,這樣會(huì)使你的代碼更加整潔中燥,代碼量還少寇甸。