View系列:View绘制:Measure测量

1:View的Measure过程发生在,View的 Draw过程之后,Layout过程之前。

2:View的Measure过程分为两种情况,第一种情况是:测量单一的View(只测量自身一个View)

第二种情况是:测量ViewGroup (即对ViewGroup视图中所有的子View都进行测量)。

3:绘制测量单一View测量流程图,绘制ViewGroup测量流程图(如下图)

     

4:源码分析 LinerLayout 复写 onMeasure()流程。(一般我们自定义View都是需要复写onMeasure函数)

5:测量模式 MeasueSpec 应用在测量过程中的地方。

Carson带你学Android:自定义View 测量过程(Measure) - 简书

目录

源码分析View/ViewGroup测量过程


一:源码分析 View的 measure测量过程

       View测量源码

# View.java

// 1 : 系统回调View的 onMeasure函数
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), 
                         widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

// 2:通过getDetaultSize() 得到View的 默认宽高
    /**
     * Utility to return a default size. Uses the supplied size if the
     * MeasureSpec imposed no constraints. Will get larger if allowed
     * by the MeasureSpec.
     *
     * @param size Default size for this view
     * @param measureSpec Constraints imposed by the parent
     * @return The size this view should be.
     */
    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;

       // 2.1 需要注意的地方,如果父类的测量模式是:AT_MOST 或者EXACTLY,那么不管子View是否 
          是 wrap_content 或者match_parent, 最终View的宽是一样的。这也是自定义View需要注 
          意的地方

        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            result = specSize;
            break;
        }
        return result;
    }

// 2.2 getDefaultSize()的默认宽度
 /**
     * Returns the suggested minimum width that the view should use. This
     * returns the maximum of the view's minimum width
     * and the background's minimum width
     *  ({@link android.graphics.drawable.Drawable#getMinimumWidth()}).
     * <p>
     * When being used in {@link #onMeasure(int, int)}, the caller should still
     * ensure the returned width is within the requirements of the parent.
     *
     * @return The suggested minimum width of the view.
     */
    protected int getSuggestedMinimumWidth() {
        return (mBackground == null) ? mMinWidth : max(mMinWidth, 
                    mBackground.getMinimumWidth());
    }

// 3: 当得到宽度或者高度了就要保存一下
   protected final void setMeasuredDimension(int measuredWidth, int measuredHeight) {
        boolean optical = isLayoutModeOptical(this);
        if (optical != isLayoutModeOptical(mParent)) {
            Insets insets = getOpticalInsets();
            int opticalWidth  = insets.left + insets.right;
            int opticalHeight = insets.top  + insets.bottom;

            measuredWidth  += optical ? opticalWidth  : -opticalWidth;
            measuredHeight += optical ? opticalHeight : -opticalHeight;
        }
        setMeasuredDimensionRaw(measuredWidth, measuredHeight);
    }



二:源码分析ViewGroup的measure测量过程

三:源码分析TextView measure测量过程

四:源码分析LinearLayout的测量过程

五:自定义View和 ViewGroup注意过程

测量注意事项


一:测量模式:MeasureSpec理解

       1: 在View测量函数  onMeasure(int size,int measureSpec) 系统会传入measureSpec参数,该参数包含三个值 :EXACTLY , AT_MOST , UNSPECIFIED

       2 :  因为View的测量流程其实就是一个递归的流程,本级View的测量函数,会传入父类的测量模式,那么根据父类的测量模式结合本级View布局参数,就可以规划出本级测量模式

      3:parentSpecMode和childLayoutParams组合关系见下图。

View学习(二)-View的测量(measure)过程 - eleven_yw - 博客园

      

二:为什么自定义View在复写measure()时,要注意如果自身尺寸wrap_content会失效

三:为什么自定义ViewGroup需要复写onMeasure函数


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值