Android View繪制流程 - 當空皓月的個人空間
剛開始時,當想要自己繪制一些自定義組件的時候,會覆蓋onDraw方法,然后,在里面利用canvas繪制一些自己想要的圖形,而最近遇到一個問題,就是onDraw函數不起作用了。然后,搜了半天資料,才知道onDraw并不是萬能的。
首先,大概介紹一下Android draw的大概流程,下面截取的是Android關于View中draw方法的一部分:
public void draw(Canvas canvas) {
final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN;
/*
* Draw traversal performs several drawing steps which must be executed
* in the appropriate order:
*
* 1. Draw the background
* 2. If necessary, save the canvas' layers to prepare for fading
* 3. Draw view's content
* 4. Draw children
* 5. If necessary, draw the fading edges and restore layers
* 6. Draw decorations (scrollbars for instance)
*/
// Step 1, draw the background, if needed
int saveCount;
if (!dirtyOpaque) {
final Drawable background = mBGDrawable;
if (background != null ) {
... ... // draw background
}
}
// skip step 2 & 5 if possible (common case)
final int viewFlags = mViewFlags;
boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0 ;
boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0 ;
if (!verticalEdges && !horizontalEdges) {
// Step 3, draw the content
if (!dirtyOpaque) onDraw(canvas);
// Step 4, draw the children
dispatchDraw(canvas);
// Step 6, draw decorations (scrollbars)
onDrawScrollBars(canvas);
// we're done...
return ;
}
...
}
可以看到,View先是繪制background,然后是自己的content,然后是dispatchDraw。繪制自己的content自然是去調用onDraw,而判斷的依據就是dirtyOpaque。而在View的構造方法中,會調用一個方法:computeOpaqueFlags,這個方法的說明如下:
protected void computeOpaqueFlags() {
// Opaque if:
// - Has a background
// - Background is opaque
// - Doesn't have scrollbars or scrollbars are inside overlay
... ... 可以看出, 判斷一個View是否為Opaque的幾個條件。顯然,對于ViewGroup(如LinearLayout…),他們是沒有background的,自然,當執行draw方法的時候,不會觸發自己的onDraw。
那么,為什么要這么做呢?這主要是考慮的性能優化,因為ViewGroup一般是用來當做容器用的,不需要承擔顯示的任務,所以,我們自己最好也不要這樣做。如果非得想要調用自己的onDraw方法,有兩個辦法:一是給ViewGroup設置一個背景色,另一個辦法就是設置setWillNotDraw為false。
實際中,我們如果想自己實現一個定制化的UI,當面對的是ViewGroup的時候,首先想到的是覆蓋dispatchDraw這個方法。
原文地址:http://lishoubo.github.io/2012/08/14/android-ondraw-and-dispatchdraw/
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!