## View的绘制流程
OnMeasure()——>OnLayout()——>OnDraw()
各步骤的主要工作:
OnMeasure():测量视图大小。从顶层父View到子View递归调用measure方法,measure方法又回调OnMeasure。
OnLayout():确定View位置,进行页面布局。从顶层父View向子View的递归调用view.layout方法的过程,即父View根据上一步measure子View所得到的布局大小和布局参数,将子View放在合适的位置上。
OnDraw():绘制视图。ViewRoot创建一个Canvas对象,然后调用OnDraw()。六个步骤:①、绘制视图的背景;②、保存画布的图层(Layer);③、绘制View的内容;④、绘制View子视图,如果没有就不用;⑤、还原图层(Layer);⑥、绘制滚动条。
invalidate
是自定义View 的时候,重新执行onDraw()方法,当view只在内容和可见度方面发生变化时调用。
postInvalidate
利用Handle消息机制,在子线程中被调用,刷新UI。
requeLayout
控件会重新执行 onMesure() onLayout() ,比如 ScrollView中有LinearLaout ,LinearLayout里面有纵向排列的ImageView和TextView,那么假如ImageView的长宽发生了变化,而要立即在手机上显示这个变化的话,就可调用 imageView.requestLayout();这样的话ScrollView 会重新执行onMesure()这个方法会确定控件的大小然后在确定出自己的宽高,最后在执行onLayout(),这个方法是对所有的子控件进行定位的。他只调用measure()和layout()过程,不会调用draw()。
dispatchDraw
ViewGroup类及其派生类具有的方法,控制子View绘制分发,重载该方法可改变子View的绘制,进而实现一些复杂的视效,典型的例子可参见Launcher模块Workspace的dispatchDraw重载。
绘制前监听
ViewTreeObserver vto =view.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
}
});
view重绘时回调
view.getViewTreeObserver().addOnDrawListener(new OnDrawListener(){
@Override
public void onDraw() {
// TODO Auto-generated method stub
}
});
view加载完成时回调
view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
}
});
获取View的尺寸
view.post(new Runnable() {
@Override
public void run() {
int width = view.getWidth();
int height = view.getHeight();
}
});