UI绘制流程
1、Measure
MeasureSpec:在Measure流程中,系统将View的LayoutParams根据父容器所施加的规则转换成对应的MeasureSpec,
在onMeasure中根据这个MeasureSpec来确定view的测量宽高
1)、测量模式
EXACTLY :父容器已经测量出所需要的精确大小,这也是childview的最终大小
------match_parent,精确值
ATMOST : child view最终的大小不能超过父容器的给的
------wrap_content
UNSPECIFIED: 不确定,源码内部使用
-------一般在ScrollView,ListView
2)、测量大小:根据测量模式来确定测量大小
3)源码里面的位运算
&:取出对应Mask类型的属性值
|:添加对应的属性值
& =~与非 或者(^异或):去掉Mask类型的属性值
2、View的测量
onMeasure方法里面调用setMeasuredDimension()确定当前View的大小
3、ViewGroup的测量
1、遍历测量Child,可以通过下面三个方法来遍历测量Child
measureChildWithMargins
measureChild
measureChildren
2、setMeasuredDimension 确定当前ViewGroup的大小
4、假如去自定义View,ViewGroup,要如何做好Measure?
1、View
套路:最终调用setMeasuredDimession方法来保存自己的测量宽高
final int specMode = MeasureSpec.getMode(measureSpec);
final int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
/* Parent says we can be as big as we want. Just don't be larger
than max size imposed on ourselves.
*/
result = Math.min(desiredSize, maxSize);
break;
case MeasureSpec.AT_MOST:
// Parent says we can be as big as we want, up to specSize.
// Don't be larger than specSize, and don't be larger than
// the max size imposed on ourselves.
result = Math.min(Math.min(desiredSize, specSize), maxSize);
break;
case MeasureSpec.EXACTLY:
// No choice. Do what we are told.
result = specSize;
break;
}
return result;
2、ViewGroup
套路:
1、测量子view的规格大小
measureChildWithMargins
measureChild
measureChildren
2、通过子view的规格大小来确定自己的大小 setMeasuredDimession
2、Layout布局过程
套路和我们Measure类似