resolveSize(int size , int measureSpec);方法介紹

resolveSize(int size , int measureSpec);
這是一個自定義view獲取size的神器,
首先我們來看下 我不知道這個方法之前獲取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行,而通過這個方法后獲得的

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //對于desireSize,只是我為了講解,只是臨時寫的一個初始值,大家要自己根據需要計算
    int desireWidthSize = 0;
    int width =resolveSize(desireWidthSize, widthMeasureSpec);
    int desireHeightSize= 0;
    int height = resolveSize(desireHeightSize, heightMeasureSpec);
    setMeasuredDimension(width, height);
}

只要8行 有沒有很吊,有沒有很吊,很簡單,縮短了整整5倍,當然這個方法我不推薦初學者立馬就使用,而是希望初學者能夠多寫寫我寫的那種,這樣子能夠更深刻的明白onmeasure這個方法的使用,以及如何實現,
那么接下來就來說下這個方法,其實這方法也是挺簡單的 接受兩個參數,size,measureSpec,
首先第一個參數的意思你希望你的view有多大,第二個參數的就是測量的measureSpec,

通過查看這個方法的源碼

/**
 * 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;
}

是這個,然后繼續(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,那么他就會告訴你  測量出的來的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);
}

耐心的仔細讀下來,就會發(fā)現,其實他就是做了幫你測量步驟,具體請看我后面的注釋

google幫你寫好了步驟,這樣會使你的代碼更加整潔,代碼量還少。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容