Android架构view自定义Android知识

MeasureSpec总结

2016-11-28  本文已影响142人  MryU93

MeasureSpec

View的LayoutParams根据父容器所施加的规则转换成对应的MeasureSpec,然后根据这个MeasureSpec来测量出View的宽高。MeasureSpec代表一个32位int值,高2位代表SpecMode(测量模式),低30位代表SpecSize(在某个测量模式下的规格大小)

//获取SpecSize:
int specSize = MeasureSpec.getSize(measureSpec)
//获取specMode
int measureSpec=MeasureSpec.makeMeasureSpec(size, mode);

SpecMode一共有三种:

  1. UNSPECIFIED :父容器不对View进行任何限制,要多大给多大,一般用于系统内部

  2. EXACTLY:父容器检测到View所需要的精确大小,这时候View的最终大小就是SpecSize所指定的值,对应LayoutParams中的match_parent和具体数值这两种模式

  3. AT_MOST :对应View的默认大小,不同View实现不同,View的大小不能大于父容器的SpecSize,对应LayoutParams中的wrap_content

MeasureSpec和LayoutParams的对应关系

View的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams共同决定。

对于普通View来说,View的measure过程由ViewGroup传递过来,measureChildWithMargins源码

protected void measureChildWithMargins(View child,
        int parentWidthMeasureSpec, int widthUsed,
        int parentHeightMeasureSpec, int heightUsed) {
    final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();

    final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
            mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
                    + widthUsed, lp.width);
    final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
            mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
                    + heightUsed, lp.height);

    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

measureChildWithMargins()方法对子元素进行measure,在调用子元素的measure方法之前先通过
measureChildWithMargins()方法得到子元素的MeasureSpec,子元素的MeasureSpec与父容器的MeasureSpec和自身的LayoutParams有关,还与view的margin和padding有关。

View 的MeasureSpec创建规则(getChildMeasureSpec方法的表格呈现)

只要提供父容器的MeasureSpec和子元素的LayoutParams,就可以确定出子元素的MeasureSpec,进一步便可以确定出测量后的大小。

上一篇下一篇

猜你喜欢

热点阅读