Android View 框架(4)-- draw

本篇你將了解到:

  1. draw 的具體流程
  2. 簡(jiǎn)單的去重寫 onDraw 方法

draw 方法

draw過程的主要流程如下:

  1. 繪制 background
  2. 如果需要的話,保存 canvaslayer,來準(zhǔn)備fading
  3. 繪制 viewcontent(調(diào)用 onDraw 方法)
  4. 繪制 childrendispatchDraw 方法)
  5. 如果需要的話,繪制 fading edges,然后還原 layer
  6. 繪制裝飾器、比如 scrollBar

下方是偽代碼,

public void draw(Canvas canvas) {
    final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
                    (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
    // Step 3, draw the content 調(diào)用onDraw方法
     if (!dirtyOpaque) onDraw(canvas);

    // Step 4, draw the children
     dispatchDraw(canvas);

    // Step 6, draw decorations (foreground, scrollbars)
     onDrawForeground(canvas);
}

其中標(biāo)志位 dirtyOpaquetrue 時(shí),是不回去調(diào)用 onDraw 方法的。而 dirtyOpaque 其實(shí)是由 privateFlags 決定的。如果我們修改了 privateFlags 的值,就可以使重寫 onDraw 被調(diào)用。

  • 方法1:設(shè)置背景
    設(shè)置背景的方法里會(huì)調(diào)用 computeOpaqueFlags 重新設(shè)置 privateFlags 。
public void setBackgroundDrawable(Drawable background) {
        computeOpaqueFlags();
        ....省略一大段代碼
        computeOpaqueFlags();
        ....省略一點(diǎn)點(diǎn)代碼
        invalidate(true);
        invalidateOutline();
    }
  • 方法2:調(diào)用 setWillNotDraw 方法
    同樣也是修改 privateFlags 達(dá)到目的。
public void setWillNotDraw(boolean willNotDraw) {
        setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
    }

重寫 onDraw

目標(biāo)效果就是在上一章的 Layout 中,添加一個(gè)圓形圖案。


image.png

關(guān)鍵代碼:

   var paint = Paint().let {
        it.color = Color.YELLOW
        it
    }
    /**
     * 不設(shè)置 background 的話,不會(huì)調(diào)用該方法
     */
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        val x = measuredWidth / 2.0F
        val y = measuredHeight / 2.0F
        canvas?.drawCircle(x, y, Math.min(x, y), paint)
    }

全部代碼 -- AViewGroup:Github 地址,是 kotlin 寫的

總結(jié)

Android View 框架(1)-- LayoutInflater
Android View 框架(2)-- measure
Android View 框架(3)-- layout
Android View 框架(4)-- draw

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容