转载请注明出处
这两天在研究View的绘制流程,看了郭霖大神的博文,再加上另一篇我转载的文章:公共技术点之 View 绘制流程。感觉整个流程顺畅多了,所以今天来整理一下思路。
我还是和上篇博文一样,自己制作了一张流程图,如果能配合以下两篇文章一起阅读则效果更佳。
http://blog.csdn.net/guolin_blog/article/details/16330267
http://a.codekk.com/detail/Android/lightSky/%E5%85%AC%E5%85%B1%E6%8A%80%E6%9C%AF%E7%82%B9%E4%B9%8B%20View%20%E7%BB%98%E5%88%B6%E6%B5%81%E7%A8%8B
先说几个背景:
1.图片中方法中的变量1,2,3,4,5,6,7代表widthMeasureSpec,heightMeasureSpec,lelf,top,right,bottom,canvas。
MeasureSpec的值由specSize和specMode共同组成的,其中specSize记录的是大小,specMode记录的是规格。
lelf,top,right,bottom分别代表子View距离父view左,上,右,下边界的距离。cavans则表示传入一个系统定义
的画布。
2.图片中[]的代表该方法最低是从哪个类中调用的。
3.绘制的过程是在ViewTootImpl类中的performTraversals中进行。最外层的View是DecorView(FrameLayout),在performTraversals中被调用,流程是measure,layout,draw。然后其开始遍历所有子View(ViewGroup)直至调用了所有View的同名方法。
总结:
1.measure在View类中被调用,不可重写。
2.onMeasure只在View和ViewGroup的子类中有具体实现。
3.layout在View 中被调用。
4.onLayout在只ViewGroup的子类中有具体实现。
5.draw在View中被调用。
6.onDraw只在具体的View中被调用。
7.draw中第二步和第五步,储存和绘制图层,一般用不上。
8.一般实现自定义View的时候重写的方法有三个onMeasure,onLayout,onDraw
添加:
-
invalidate()
请求重绘 View 树,即 draw 过程,假如视图发生大小没有变化就不会调用layout()
过程,并且只绘制那些调用了invalidate()
方法的 View。 -
requestLayout()
当布局变化的时候,比如方向变化,尺寸的变化,会调用该方法,在自定义的视图中,如果某些情况下希望重新测量尺寸大小,应该手动去调用该方法,它会触发measure()
和layout()
过程,但不会进行 draw。