您的位置:首页 > 其它

MeasureSpec类的分析以及View的工作流程

2016-09-08 21:36 225 查看
MeasureSpec是View的内部类。下面看看MeasureSpec的官方定义。

MeasureSpec把从父布局传到子布局的参数封装到布局中。每一个MeasureSpec对象代表着高或者宽。MeasureSpec由大小和模式组成,是一个32位的int值,最高2位代表着SpecMode(测量模式),最低30位代表着SpecSize(规格大小)。SpecMode有三种模式,分别是

UNSPECIFIED //父布局没有强加子布局的大小约束,所以子布局可以有任意的大小
EXACTLY //父布局设定了子布局的大小,子布局不能超过这个大小
AT_MOST //子布局可以用任意具体值来设定其大小


现在看看View的工作流程

View的工作流程总结为三步

measure 测量

layout 布局

draw 绘制

下面,看看View的测量过程。

由源码可知,View的measure方法是final方法,子类不能修改它。最后会调用onMeasure方法。

public final void measure(int widthMeasureSpec, int heightMeasureSpec)


下面是onMeasure方法实现

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}


上面的onMeasure方法调用setMeasuredDimension方法来设置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;
break;
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}


可以知道,不同的测量模式有不同的测量大小。

在UNSPECIFIED模式下,传入的大小size就是返回的测量大小,其它模式都是measureSpec的specSize的大小。

下面看看获取size的方法

protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}
//mBackground是Drawable对象
private Drawable mBackground;


可以知道,如果View没有设置背景,那么测量的宽度就是mMinWidth ,对应属性android:minWidth的大小。如果设置了背静,就是Drawable的大小(Drawable没有设置大小默认是0)

下面,看看View的layout过程。

layout方法中会调用onLayout方法来确定View的位置,这时候的View的大小是实际展现出来的大小。

下面,看看View的绘制过程。

绘制过程

绘制背景backgroud.draw(canavs)

绘制自己(onDraw)

绘制children(dispacthDraw)

绘制装饰(onDrawScrollBars)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: