1).Android 深入理解 View 的绘制流程和机制
http://blog.csdn.net/whb20081815/article/details/62236641
2).
http://blog.csdn.net/whb20081815/article/details/62419059
3).Android 动画用法+原理(Property Animation) 酷炫 UI动画
http://blog.csdn.net/whb20081815/article/details/64501074
http://blog.csdn.net/whb20081815/article/details/744747
同样是程序员差距咋就这么大呢?
ViewRoot:看源码直接搜索不到,需到源码网站看
View系统的绘制流程会从ViewRoot的performTraversals()方法中开始,performTraversals()的意思是:执行遍历
View的整个绘制流程可以分为以下三个阶段:
Android系统的视图结构的设计也采用了组合模式
总结:从以上分析可以看出View树的绘制是一个递归的过程,从ViewGroup一直向下遍历,直到所有的子view都完成绘制,那这一切的源头在什么地方(是谁最发起measure、layout和draw的)?当然就是在View树的源头了——ViewRoot!,ViewRoot中包含了窗口的总容器DecorView,ViewRoot中的performTraversal()方法会依次调用decorView的measure、layout、draw方法,从而完成view树的绘制。
onAttachedToWindow () 和 onDetachedFromWindow ()
onAttachedToWindow是在第一次onDraw前调用的。也就是我们写的View在没有绘制出来时调用的,但只会调用一次。
onDetachedFromWindow:销毁资源(既销毁view)之后调用。
veiw状态的保持:onSaveInstanceState()方法
Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:
Android UI操作并不是线程安全的,并且这些操作必须在UI线程中调用。
invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能
看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中pop掉。
Android 程序默认情况下也只有一个进程,但一个进程下却可以有许多个线程。在这么多线程当中,把主要是负责控
制UI界面的显示、更新和控件交互的线程称为UI线程,由于onCreate()方法是由UI线程执行的,所以也可以把UI线程理解
为主线程。其余的线程可以理解为工作者线程。invalidate()得在UI线程中被调动,在工作者线程中可以通过Handler来通
知UI线程进行界面更新。而postInvalidate()在工作者线程中被调用。
问题二:
Android View刷新机制
由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该视图需要重绘时,就会为该View添加该标志位。
调用流程 :
mView.draw()开始绘制,draw()方法实现的功能如下:
绘制该View的背景
为显示渐变框做一些准备操作(见5,大多数情况下,不需要改渐变框)
调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)
调用dispatchDraw ()方法绘制子视图(如果该View类型不为ViewGroup,即不包含子视图,不需要重载该方法)值得说明的是,ViewGroup类已经为我们重写了dispatchDraw ()的功能实现,应用程序一般不需要重写该方法,但可以重载父类函数实现具体的功能。
在Android的布局体系中,父View负责刷新、布局显示子View;而当子View需要刷新时,则是通知父View来完成。这种处理逻辑在View的代码中明确的表现出来:
子View调用invalidate时,首先找到自己父View(View的成员变量mParent记录自己的父View),然后将AttachInfo中保存的信息告诉父View刷新自己。
总结回答:
measure()方法,layout(),draw()三个方法主要存放了一些标识符,来判断每个View是否需要再重新测量,布局或者绘制,主要的绘制过程还是在onMeasure,onLayout,onDraw这个三个方法中
1.onMesarue() 为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性: mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。
2.onLayout() 为将整个根据子视图的大小以及布局参数将View树放到合适的位置上。
3.onDraw() 开始绘制图像,绘制的流程如下
首先绘制该View的背景
调用onDraw()方法绘制视图本身 (每个View都需要重载该方法,ViewGroup不需要实现该方法)
如果该View是ViewGroup,调用dispatchDraw ()方法绘制子视图
参考博客:
http://mp.weixin.qq.com/s?__biz=MzI0MjE3OTYwMg==&mid=401462221&idx=1&sn=dda1f3500c993d643dcdae6dd2cc3d6f&scene=21#wechat_redirect