View的绘制流程
作者:互联网
在设计一个不能简单拼凑的自定义控件的时候,就需要设计人员自己实现控件的测量、布局和绘制等操作,而这需要熟练掌握View
的绘制流程。
1. Android
的UI
管理系统的层级关系
Activity
是最外层载体,代表一个完整的用户界面,当我们使用setContentView
方法来设置用户视图的时候,就会在DecorView
中进行相关的渲染。而PhoneWindow
是Activity
和View
的系统交互的接口。
1.2 绘制的整体流程
当应用启动,会启动一个主Activity
,并渲染关联的布局文件。绘制从根视图ViewRoot
的performTraversals()
方法开始,从上到下遍历整个视图树,每个View
控件负责绘制自己,而ViewGroup
还需要负责通知自己的子View
进行绘制操作。视图的绘制过程可以分为下面三个步骤:
Measure
测量;Layout
布局;Draw
绘制;
在VeiwRoot
中的performTraversals()
方法中的核心代码如下:
private void performTraversals(){
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
// 执行测量流程
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
// 执行布局流程
performLayout(xxx);
// 执行绘制流程
performDraw();
}
注意到上面也就是前面提到的三个步骤的调用,那么MeasureSpec
又是什么?
1.3 MeasureSpec
注意到是int
申明,是一个整型值,32
位。
- 高
2
位表示测量的模式SpecMode
; - 低
30
位,表示某种测量规格下的SpecSize
;
MeasureSpec
是View
类下的一个静态内部类,用来说明应该如何测量这个Veiw
。
public static class MeasureSpec {
// 最大值测量模式
public static final int AT_MOST = -2147483648;
// 精确测量模式
public static final int EXACTLY = 1073741824;
// 不指定测量模式
public static final int UNSPECIFIED = 0;
public MeasureSpec() {
throw new RuntimeException("Stub!");
}
// 根据指定的大小和模式,创建一个MeasureSpec
public static int makeMeasureSpec(int size, int mode) {
throw new RuntimeException("Stub!");
}
public static int getMode(int measureSpec) {
throw new RuntimeException("Stub!");
}
public static int getSize(int measureSpec) {
throw new RuntimeException("Stub!");
}
public static String toString(int measureSpec) {
throw new RuntimeException("Stub!");
}
}
UNSPECIFIED
不指定测量模式,很少用到。
EXACTLY
精确测试模式,表示当该视图的layout_width
或者layout_height
被指定位具体数值或者match_parent
时生效。
AT_MOST
最大值模式,当视图的layout_width
或者layout_height
被指定为wrap_content
时生效,此时的视图尺寸可以时不超过父视图允许的最大尺寸的任何值。
参考:Android高级进阶
标签:MeasureSpec,int,流程,视图,static,绘制,public,View 来源: https://blog.csdn.net/qq_26460841/article/details/114757684