(1)MeasureSpec是什么?
重写过onMeasure()方法都知道,测量须要用到MeasureSpec类获取View的测量模式和大小,那么这个类是怎样存储这两个信息呢?html
留心观察的话会发现,onMeasure方法的两个参数实际是32位int类型数据,即:canvas
而其结构为 mode + size ,前2位为mode,然后30位为size。app
==> getMode()方法(measureSpec --> mode):
getSize()方法同理。ide
==> makeMeasureSpec()方法(mode + size --> measureSpec):
这里解释一下,按位或左侧为size的高2位清零后的结果,右侧为mode的低30位清零后的结果,二者按位或运算的结果正好为高2位mode、低30位size,例:布局
二进制计算规则可参考:
==> 测量模式:
UNSPECIFIED:父容器不对View做任何限制,系统内部使用。rest
EXACTLY:精确模式,父容器检测出View大小,即为SpecSize;对应LayoutParams中的match_parent和指定大小的状况。code
AT_MOST:最大模式,父容器指定可用大小,View的大小不能超出这个值;对应wrap_content。orm
(2)ViewGroup的测量流程
回到ViewRootImpl的performMeasure方法,这里传入的参数为顶层DecorView的测量规格,其测量方式为:htm
match_parent和具体数值大小为EXACTLY模式,wrap_content则为AT_MOST模式。
往下走,performMeasure方法中调用了DecorView的onMeasure方法,而DecorView继承自FrameLayout,能够看到FL的onMeasure方法中调用了measureChildWithMargins方法,并传入自身的测量规格:
即测量子控件的大小,测量规则详情可看getChildMeasureSpec方法,总结以下:
childLayoutParams\parentSpecMode
EXACTLY
AT_MOST
UNSPECIFIED
dp
EXACTLY/childSize
EXACTLY/childSize
EXCATLY/childSize
match_parent
EXACTLY/parentSize
AT_MOST/parentSize
UNSPECIFIED/0
wrap_content
AT_MOST/parentSize
AT_MOST/parentSize
UNSPECIFIED/0
回到onMeasure方法,测完子控件以后,ViewGroup会通过一些计算,得出自身大小:
综上,ViewGroup的测量须要先测量子View的大小,然后结合padding等属性计算得出自身大小。
(3)View的测量流程
能够看到setMeasuredDimensionRaw()方法:
View不须要考虑子View的大小,根据内容测量得出自身大小便可。
另外,View中的onMeasure方法中调用到getDefaultSize方法:
这里看到精确模式和最大模式,最终测量的结果都是父容器的大小,即布局中的wrap_content、match_parent以及数值大小效果都同样,这也就是自定义View必定要重写onMeasure方法的缘由。
布局相对测量而言要简单许多,从ViewRootImpl的performLayout方法出发,能够看到其中调用了DecorView的layout方法:
进入layout方法,发现l、t、r、b被传递到了setFrame方法中,并设置给了成员变量:
因此,布局实际为调用View的layout方法,设置自身的l、t、r、b值。另外,layout方法中往下走,能够看到调用了onLayout方法,进入后发现为空方法。于是查看FrameLayout的onLayout方法:
能够看到,进行一系列计算后,调用了child的layout方法,对子控件进行布局,同时子控件又会继续往下对本身的子控件布局,从而实现遍历。
综上,布局实际为调用layout方法设置View位置,ViewGroup则须要另外实现onLayout方法摆放子控件。
(1)绘制过程入口
(2)绘制步骤
进入到View的draw方法中,能够看到如下一段注释:
结合draw方法的源码,绘制过程的关键步骤以下:
==> 绘制背景:drawBackground(canvas)
==> 绘制本身:onDraw(canvas)
==> 绘制子view:dispatchDraw(canvas)
==> 绘制滚动条、前景等装饰:onDrawForeground(canvas)
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h61825.shtml