resolveSize(int size , int measu

作者: bogerLiu | 来源:发表于2017-03-01 16:05 被阅读201次

    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帮你写好了步骤,这样会使你的代码更加整洁,代码量还少。

    相关文章

      网友评论

        本文标题:resolveSize(int size , int measu

        本文链接:https://www.haomeiwen.com/subject/mlfcgttx.html