Android中dispatchDraw分析

Android中dispatchDraw分析

View中:

public void draw(Canvas canvas) {

/*

1. Draw the background   繪製背景

2. If necessary, save the canvas' layers to prepare for fading  如有必要,顏色漸變淡之前保存畫布層(即鎖定原有的畫布內容)

3. Draw view's content  繪製view的內容

4. Draw children    繪製子view

5. If necessary, draw the fading edges and restore layers   如有必要,繪製顏色漸變淡的邊框,並恢復畫布(即畫布改變的內容附加到原有內容上)

6. Draw decorations (scrollbars for instance)   繪製裝飾,比如滾動條

*/

   ...

   if (!dirtyOpaque) {

       drawBackground(canvas); //背景繪製

   }

   // skip step 2 & 5 if possible (common case) 通常情況跳過第2和第5步

   ...

   if (!dirtyOpaque) onDraw(canvas); //調用onDraw

   dispatchDraw(canvas);   //繪製子view

   onDrawScrollBars(canvas); //繪製滾動條

   ...

}

protected void dispatchDraw(Canvas canvas) { //空實現 }

protected void onDraw(Canvas canvas) { //空實現 }


ViewGroup中:

protected void dispatchDraw(Canvas canvas) {

    ...

    drawChild(...); //繪製子view

    ...

}


protected boolean drawChild(Canvas canvas, View child, long drawingTime) {

        return child.draw(canvas, this, drawingTime);

}



說明:

1. 自定義一個view時,重寫onDraw。

    調用view.invalidate(),會觸發onDraw和computeScroll()。前提是該view被附加在當前窗口上

    view.postInvalidate(); //是在非UI線程上調用的


2.  自定義一個ViewGroup,重寫onDraw。

     onDraw可能不會被調用,原因是需要先設置一個背景(顏色或圖)。

           表示這個group有東西需要繪製了,纔會觸發draw,之後是onDraw。

    因此,一般直接重寫dispatchDraw來繪製viewGroup


3. 自定義一個ViewGroup

    dispatchDraw會調用drawChild。


總結:

繪製VIew本身的內容,通過調用View.onDraw(canvas)函數實現

繪製自己的孩子通過dispatchDraw(canvas)實現


    View組件的繪製會調用draw(Canvas canvas)方法,draw過程中主要是先畫Drawable背景,對 drawable調用setBounds()然後是draw(Canvas c)方法.有點注意的是背景drawable的實際大小會影響view組件的大小,drawable的實際大小通過getIntrinsicWidth()和getIntrinsicHeight()獲取,當背景比較大時view組件大小等於背景drawable的大小
     畫完背景後,draw過程會調用onDraw(Canvas canvas)方法,然後就是dispatchDraw(Canvas canvas)方法, dispatchDraw()主要是分發給子組件進行繪製,我們通常定製組件的時候重寫的是onDraw()方法。值得注意的是ViewGroup容器組件的繪製,當它沒有背景時直接調用的是dispatchDraw()方法, 而繞過了draw()方法,當它有背景的時候就調用draw()方法,而draw()方法裏包含了dispatchDraw()方法的調用。因此要在ViewGroup上繪製東西的時候往往重寫的是dispatchDraw()方法而不是onDraw()方法,或者自定製一個Drawable,重寫它的draw(Canvas c)和 getIntrinsicWidth(), getIntrinsicHeight()方法,然後設爲背景。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章