本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点
View的三大流程指的是measure(测量)、layout(布局)、draw(绘制)。
下面我们来分别看看这三大流程
View的measure(测量)
MeasureSpec
MeasureSpec是View的一个内部静态类
//view.class
public static class MeasureSpec {
private static final int MODE_SHIFT = 30;
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
...
/**
* 这种模式不用关心
*/
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
/**
* 精确模式,对应的是match_parent和具体值,比如100dp
public static final int EXACTLY = 1 << MODE_SHIFT;
/**
* 最大模式,对应的就是wrap_content
*/
public static final int AT_MOST = 2 << MODE_SHIFT;
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
@MeasureSpecMode int mode) {
if (sUseBrokenMakeMeasureSpec) {
return size + mode;
} else {
return (size & ~MODE_MASK) | (mode & MODE_MASK);
}
}
/**
* 获取测量的模式
*/
@MeasureSpecMode
public static int getMode(int measureSpec) {
//noinspection ResourceType
return (measureSpec & MODE_MASK);
}
/**
* 获取测量到的尺寸大小
*/
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
...
}
MeasureSpec总结起来就是:
- 它由2部分数据组成,分别为定义了View测量的模式和View的测量尺寸大小
- 其中EXACTLY精确模式表示的是match_parent和具体值;AT_MOST最大模式表示的是wrap_content的情况
View的measure过程
View的measure过程由其measure方法完成,在measure方法中会调用View的onMeasure方法
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}
setMeasuredDimension方法会设置View的测量宽高,所以我们知道getDefaultSize方法返回的就是View的测量宽高。我们来看看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;