欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
  (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