## 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();
}
});