View的layout過程和draw過程

View的layout過程

下面是表達(dá)其大概思路的偽碼

public void layout(int l, int t, int r, int b){
      setFrame(l ,t , r, b);
      onLayout(changed ,l , t, r, b);
}

上面的思路也很清晰,就是首先傳入了l ,t, r, b四個參數(shù),然后調(diào)用setFrame(l, t, r, b)方法,通過setFrame()方法來設(shè)定View的四個頂點的位置,這樣就設(shè)定了View在父容器中的位置。接著就調(diào)用onLayout()方法,這個方法的用途就是父容器確定其中所有子View的位置。有個地方需要注意:layout(int l, int t, int r, int b)中這四個參數(shù)是誰傳入的?其實,就父View的onLayout()方法中調(diào)用子view的layout()方法時傳入的。
同樣,由于onLayout()的具體實現(xiàn)和具體的布局有關(guān),所以View和ViewGroup均沒有真正地實現(xiàn)onLayout()方法,總體來說,偽碼實現(xiàn)如下:

protected void onLayout(boolean changed, int l, int t, int r, int b){
      for (int i = 0; i < count; i ++){
            View child = getVirtualChildAt(i);
            ......   //   獲取對應(yīng)child的childLeft, childTop , childRight, childBottom數(shù)據(jù)
            child.layout(childLeft, childTop , childRight, childBottom);       //注解一
      }
}

注解一:
注意這里的childLeft, childTop , childRight, childBottomd都是需要根據(jù)具體情況計算而來的。

View的draw過程

View的draw過程比較簡單,下面使用偽碼來表明整個過程

public void draw(Canvas canvas){
      ...
      //step 1 繪制背景
      drawBackground(canvas);
      //step 2 繪制自己
      onDraw(canvas);
      //step 3 繪制子View
      dispatchDraw(canvas);         //注解一
      //step 4 繪制裝飾
      onDrawScrollBars(canvas);
      ...
      return;
}

//注解一
View繪制過程的傳遞是通過dispatchDraw()來實現(xiàn)的,dispatchDraw()會遍歷所有的子元素的draw()方法,如此draw事件就一層層地傳遞下去了。
還有一個地方需要注意,View有一個特殊的方法setWillNotDraw():

public void setWillNotDraw(boolean willNotDraw){
      setFlags(willNotDraw ? WILL_NOT_DRAW : 0 , DRAW_MASK);
}

如果一個View不需要繪制任何內(nèi)容,那么設(shè)置這個標(biāo)志位為true以后,系統(tǒng)就會進(jìn)行相應(yīng)的優(yōu)化。默認(rèn)情況下,View沒有啟用這個標(biāo)志位,但是ViewGroup會默認(rèn)啟用這個優(yōu)化標(biāo)志位。這個標(biāo)志位的實際開發(fā)意義:當(dāng)我們自定義控件繼承ViewGroup并且本身不具備繪制功能時,就可以開啟這個標(biāo)記位從而便于系統(tǒng)進(jìn)行后續(xù)的優(yōu)化。如果知道一個ViewGroup需要通過onDraw()來繪制自身內(nèi)容時,我們需要顯式地關(guān)閉WILL_NOT_DRAW這個標(biāo)記位。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容