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

是这个,然后继续看

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

耐心的仔细读下来,就会发现,其实他就是做了帮你测量步骤,具体请看我后面的注释

google帮你写好了步骤,这样会使你的代码更加整洁,代码量还少。

    原文作者:bogerLiu
    原文地址: https://www.jianshu.com/p/5d490ab147f8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞