美文网首页
Android笔记 View onMeasure

Android笔记 View onMeasure

作者: blossom_6694 | 来源:发表于2018-04-10 15:24 被阅读0次

    一、 onMeasure
    onMeasure方法用于测量View 的大小。当子类重写这个方法时,必须调用setMeasuredDimension,不然会抛出 IllegalStateException。

    
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
    
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    
    }
    
    

    二、getSuggestedMinimumWidth
    如果View没有设置背景则返回mMinWidth(对应布局中的miniWidth, 或view.setMinimumWidth) ,如果设置了背景就返回mMinWidth 和Drawable最小宽度两个值的最大值。

    
    protected int getSuggestedMinimumWidth() {
    
        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
    
    }
    
    

    三、MeasureSpec
    MeasureSpec 用来表示测量模式和大小,它是一个32位的int值,高两位为specMode (测量的模式),低30位为specSize (测量的大小),测量模式分为三种:

    UNSPECIFIED:未指定模式,View想多大就多大,父容器不做限制,一般用于系统内部的测量。

    AT_MOST:最大模式,对应于wrap_comtent属性,只要尺寸不超过父控件允许的最大尺寸就行。

    EXACTLY:精确模式,对应于match_parent属性和具体的数值,父容器测量出View所需要的大小,也就是specSize的值。

    四、getDefaultSize

    
    public static int getDefaultSize(int size, int measureSpec) {
    
        int result = size;
    
        int specMode = MeasureSpec.getMode(measureSpec);
    
        int specSize = MeasureSpec.getSize(measureSpec);
    
        switch (specMode) {
    
        case MeasureSpec.UNSPECIFIED:
    
            result = size;
    
            break;
    
        case MeasureSpec.AT_MOST:
    
        case MeasureSpec.EXACTLY:
    
            result = specSize;
    
            break;
    
        }
    
        return result;
    
    }
    
    

    五、setMeasuredDimension

    
    protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
    
        boolean optical = isLayoutModeOptical(this);
    
        //判断当前view的LayoutMode是否为opticalbounds
    
        //ViewGroup 里面的方法, clipBounds就是默认值,不处理一些控件之间的“留白”,opticalBounds消除控件之间的留白
    
        if (optical != isLayoutModeOptical(mParent)) {
    
            Insets insets = getOpticalInsets();
    
            int opticalWidth  = insets.left + insets.right;
    
            int opticalHeight = insets.top  + insets.bottom;
    
            //如果是opticalBounds 模式,则需要加上“留白”的空间,如果是clipBounds模式,则要减去“留白”的空间
    
            measuredWidth  += optical ? opticalWidth  : -opticalWidth;
    
            measuredHeight += optical ? opticalHeight : -opticalHeight;
    
        }
    
        setMeasuredDimensionRaw(measuredWidth, measuredHeight);
    
    }
    
    private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
    
        mMeasuredWidth = measuredWidth;
    
        mMeasuredHeight = measuredHeight;
    
        mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
    
    }
    
    

    相关文章

      网友评论

          本文标题:Android笔记 View onMeasure

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