Andorid view 的onMeasure():
1 | @Override |
1. 理解MeasureSpec
从onMeasure
方法参数可以看到两个int值,那么怎么通过他来获取测量信息呢?
其实MeasureSpec是一view的内部类,其封装了view的规格尺寸。他有一个很重要的常量,就是一个32位的int 值,很巧妙,其中高2位代表了SpecMode,低30位代表了SpecSIze,(从其源码可以看出)
- SpecMode 指测量模式:
- UNSPECIFIED:未指定模式未指定模式,View想多大就多大,父容器不做限制,一般用于系统内部的测量
- AT_MOST:最大模式,对应于wrap_comtent属性,子View的最终大小是父View指定的SpecSize值,并且子View的大小不能大于这个值。
- EXACTLY:精确模式,对应于 match_parent 属性和具体的数值,父容器测量出 View所需要的大小,也就是SpecSize的值
所以一般自定义view需要重写该方法,给出当测量模式为AT_MOST时的默认宽高大小,否则,当设置其宽高为wrap_content时会和match_parent一样
2.view的Measure流程:
measure 用来测量 View 的宽和高,它的流程分为 View 的 measure 流程和 ViewGroup 的measure流程,只不过ViewGroup的measure流程除了要完成自己的测量,还要遍历地调用子元素的measure()方法。
在自定义view的时候,一般需要处理padding和子元素的margin两种情况
3.两种获取view的宽高方法对比:
getMeasuredWidth()
1
2
3public final int getMeasuredWidth() {
return mMeasuredWidth & MEASURED_SIZE_MASK;
}getHeight()
1
2
3public final int getHeight() {
return mBottom - mTop;
}所以从其源码可以看出不同,第一个需要在其onMeasure()方法调用后才能获取到正确的宽高,而第二个需要在onLayout()调用后才能获取到