Learn && Live
虚度年华浮萍于世,勤学善思至死不渝
前言
Hey,欢迎阅读Connor学Android系列,这个系列记录了我的Android原理知识学习、复盘过程,欢迎各位大佬阅读斧正!原创不易,转载请注明出处:http://t.csdn.cn/pIpx0,话不多说我们马上开始!
1.ViewRoot
ViewRoot对应于ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成的。在ActivityThread中,当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象和DecorView建立关联
root = new ViewRootImpl(view.getContext(), display);
root.setView(view, wparams, panelParentView);
2.DecorView
DecorView作为顶级View,继承了FrameLayout,一般情况下它内部会包含一个竖直方向的LinearLayout,在这个LinearLayout中分为上下两部分,上面是标题栏,下面是内容栏(id是content)。View层的事件都先经过DecorView,然后才传递给我们的View
3.MeasureSpec
MeasureSpec代表一个32位int值,高2位代表SpecMode,指测量模式;低30位代表SpecSize,指某种测量模式下的规格大小
打包和解包
MeasureSpec通过将SpecMode和SpecSize打包成一个int值来避免过多的对象内存分配,为了方便操作,提供了打包和解包方法
即一组SpecMode和SpecSize可以打包为一个MeasureSpec,一个MeasureSpec可以解包得到原始的SpecMode和SpecSize
注意这里的MeasureSpec指MeasureSpec所代表的int值,而非MeasureSpec本身
SpecMode
-
UNSPECIFIED 父容器不对View有任何限制,要多大给多大,一般用于系统内部,表示一种测量的状态
-
EXACTLY View的最终大小就是SpecSize所指定的值,对应match_parent和指定具体数值这两种模式
-
AT_MOST 父容器指定了一个可用大小,即SpecSize,View的大小不能大于这个值,具体是什么由View的具体实现决定。对应wrap_content模式
4.MeasureSpec和LayoutParams的对应关系
在View测量时,系统会将LayoutParams在父容器的约束下转换成对应的MeasureSpec,再根据MeasureSpec来确定View测量后的宽/高
(1)DecorView(顶级View):MeasureSpec由窗口尺寸和自身的LayoutParams共同确定
(2)普通View:MeasureSpec由父容器的MeasureSpec、自身的LayoutParams和View的margin及padding共同确定
MeasureSpec确定后便可在onMeasure中确定View的测量宽/高
DecorView
- LayoutParams.MATCH_PARENT:精确模式,大小就是窗口的大小
- LayoutParams.WRAP_CONTENT:最大模式,大小不定,但不能超过窗口的大小
- 固定大小(比如100dp):精确模式,大小即为LayoutParams指定的大小
普通View
(parentSize指父容器中目前可使用的大小)
注意wrap_content模式下,不管父容器的模式是EXACTLY还是AT_MOST,View的模式总是AT_MOST且大小为parentSize