View、ViewGroup的测量、布局、绘制流程

注:

1、为了方便描述,假定现在有三层布局,分别为:最外层View1、第二层View2、第三层View3;
2、下面“测量子控件、布局子控件、绘制子控件”的思路都是:用for循环遍历子控件,调用子控件的measure()、layout()、draw()方法。下面就不对此进行解释。

测量

measure(int widthMeasureSpec, int heightMeasureSpec){}
1、该方法在View类中,所有子类都是调用这个方法;
2、参数是自身的MeasureSpec,由父控件计算后传递过来;
3、该方法做2件事:
①计算出最终的MeasureSpec
②调用自身的onMeasure()方法,将MeasureSpec传递过去;

onMeasure(int widthMeasureSpec, int heightMeasureSpec){}
1、该方法由每个控件自己重写,因为不同控件测量规则不一样;
2、该方法做2件事:
①调用measureChildren()方法测量子控件;
②计算自身尺寸值(子控件测量完毕后,才能确定自身尺寸);

measureChildren(){}
1、该方法在ViewGroup类中,所有ViewGroup子类都调用这个方法;
2、该方法测量子控件;

测量流程总结:View1.measure()——View1.onMeasure()——View1.measureChiledren()——View2.measure()——View2.onMeasure()——View2.measureChiledren()——View3.measure()——View3.onMeasure()——View3.measureChiledren()

布局

所谓布局,就是确定控件的位置,即确定其上下左右座标值

layout(int l, int t, int r, int b){}
1、该方法在View类中,所有子类都是调用这个方法(不同控件,在调这个方法之前会进行一些其它处理);
2、参数是自身的上下左右座标值,由父控计算后件传递过来;
3、该方法做2件事:
①设置自身上下左右座标值;
②调用自身的onLayout()方法对子控件进行布局;

onLayout(boolean changed, int left, int top, int right, int bottom){}
1、该方法由每个具体类自己重写,因为不同的控件,布局规则不一样;
2、该方法布局子控件;

布局流程总结:View1.layout()——View1.onLayout()——View2.layout()——View2.onLayout()——View3.layout()——View3.onLayout()

绘制

draw(Canvas canvas){}
1、该方法在View类中,所有子类都是调用这个方法;
2、参数canvas在所有控件中传递,即该布局中的所有子控件都用同一个canvas;
2、这个方法中启动绘制流程(下面为简化流程):一些初始化计算——绘制背景——onDraw()绘制自身——dispatchDraw()绘制子控件;

onDraw(Canvas canvas){}
1、该方法在View类中是空实现,所有具体控件具体实现;
2、该方法绘制自身;

dispatchDraw(Canvas canvas){}
1、该方法在ViewGroup类中,所有子类都是调用这个方法;
3、该方法绘制子控件;

绘制流程总结:View1.draw()——View1.onDraw()——View1.dispatchDraw()——View2.draw()——View2.onDraw()——View2.dispatchDraw()——View3.draw()——View3.onDraw()——View3.dispatchDraw()

总结

1、这三个流程都是在ViewRoot中启动,启动方法分别为performMeasure()、performLayout()、performDraw()

2、measure()、layout()、draw()是启动流程,没有各个控件专属的东西,所以在基类View中,子类共用代码;

3、onMeasure()、onLayout()、onDraw()是具体的测量、布局、绘制工作,各个控件不一样,所以各个控件自己实现;

4、measureChildren()、dispatchDraw()的作用是:遍历子控件、调用其measure()/draw()方法。没有各个控件专属的东西,所以在父类ViewGroup中,子类共用代码;

5、布局是个例外,没有layoutChildren()方法,因为每个控件布局规则不一样,无法重用代码,所以“布局子控件”放在onLayout()方法中实现;

发布了35 篇原创文章 · 获赞 52 · 访问量 8万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章