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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!