ViewRoot & DecorView
基本概念
ViewRoot对应ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均通过ViewRoot来完成。
ActivityThread中,Activity创建完成后,会将DecorView添加到Window中,同时创建ViewRootImpl对象,并建立ViewRootImpl与DecorView的关联。
View的绘制流程: performTraversals-->measure-->layout-->draw, 其中measure测量view的宽和高, layout确定了View在父容器中存放的位置(4个顶点坐标), draw负责绘制在屏幕上。
DecorView作为顶级的view, 一般包含标题栏和内容栏, Activity代码中setContentView()是将布局文件加到内容栏中(所以, 当我们在布局文件中自定了toolbar的时候, 该Activity的属性就要声明NoActionBar); 并且, 所有的View层的事件需要通过DecorView再传递给View
MeasureSpec
决定了View的尺寸规格
MeasureSpec代表了一个32位int值, 高2位代表SpecMode(测量模式), 低30位代表SpecSize(规格大小)。用32位值来纪录,是为了避免过多的对象占用内存。
SpecMode 3中类型: UNSPECIFIED父容器不对view有任何限制, 要多大有多大, 一般用于系统内部; EXACTLY 父容器已经检测出View所需要的精确大小, 此时View的大小就是SpecSize所指定的值; AT_MOST, 父容器指定了一个可用大笑SpecSize, View大小不能大于这个值, 对应于layout中的wrap_content
MeasureSpec 与LayoutParams对应关系
系统内部通过MeasureSpec来进行View的测量, 我们可以给View设置LayoutParams, 在View测量的时候, 系统会将LayoutParams在父容器的约束下转化成MeasureSpec, 再确定其宽和高。
一般指定LayoutParams的三种模式: Match_parent, wrap_content, 具体的值
需要注意的是:
LayoutParams需要和父容器一起才能决定view的MeasureSpec。对于DecorView, 其MeasureSpec由窗口的尺寸和自身的LayoutParams决定。
网友评论