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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章