自定義ViewGroup中child繪製順序

2021-10-23 16:16:02 字數 2430 閱讀 3065

在專案中需要顯示一組使用者頭像(見下圖),右邊的有一部分在左邊的下面,依次疊加。

我們可以使用linearlayout,然後每個向左偏移-xdp,但是這樣做你會發現實現的效果並不是這樣,而是右邊的頭像在左邊的頭像上面。

這是因為viewgroup繪製子view的順序導致的,先新增的view先繪製,我們可不可以改變viewgroup的繪製順序呢,當然可以,在view中有乙個方法settranslationz(float translationz),translationz值越大優先順序就越低,這個方法雖然可以實現我們的效果,但是只能在5.0及以上版本上使用,我們的專案最低版本是4.1,因此也就不能用這個方法。還有沒有其他方法可以改變繪製順序呢,只有去看下viewgroup的原始碼了。

找到viewgroup中dispatchdraw方法,這個方法作用是遍歷viewgroup中所有的子view繪製出來。

@override

protected

void

dispatchdraw

(canvas canvas)}.

....

.}

先看注釋①,獲取預定義的排序列表,判斷沒有使用硬體加速則呼叫buildorderedchildlist方法,

arraylist

buildorderedchildlist()

else

final

boolean customorder =

ischildrendrawingorderenabled()

;//④

for(

int i =

0; i < childrencount; i++

) mpresortedchildren.

add(insertindex, nextchild);}

return mpresortedchildren;

}

buildorderedchildlist方法中 ,注釋④呼叫ischildrendrawingorderenabled方法,這個方法是控制是否開啟自定義排序,預設是返回false,注釋⑤中呼叫getandverifypreorderedindex方法,獲取view的順序

private

intgetandverifypreorderedindex

(int childrencount,

int i,

boolean customorder)

childindex = childindex1;

}else

return childindex;

}

注釋⑧呼叫getchilddrawingorder方法,這個方法是根據順序獲取view下標,可以自定義順序,如果沒有開啟自定義順序預設繪製順序也view的新增順序,也就是說我們可以覆蓋這個方法,返回我們自己定義的順序,從而改變子view的繪製順序。我們通過getandverifypreorderedindex獲取到了view的繪製順序後回到注釋⑥,這裡獲取view的translationz值,然後迴圈確保translationz值小的在值大前面。最後執行完buildorderedchildlist方法後重新重新排序的子view列表。

最後回到dispatchdraw方法注釋③迴圈遍歷獲取子view列表依次繪製子view。

看完原始碼,我們就知道怎麼自定義子view繪製順序了

1.重寫ischildrendrawingorderenabled方法返回true,表示開啟自定義繪製順序

2.重寫getchilddrawingorder方法,根據自己實際需求返回view的順序。由於新新增的view先繪製,所以我們需要倒序返回。

**如下:

class

customorderdrawchildlinearlayout

(context: context?

, attrs: attributeset?):

linearlayout

(context, attrs)

override

fungetchilddrawingorder

(childcount: int, i: int)

: int

}

自定義ViewGroup(一)

1 概述 viewgroup是乙個view的容器,他可以給出childview的測量模式和測量其寬高,他的作用非常重要。childview測量模式 exactly 表示設定了精確的值,一般當childview設定其寬 高為精確值 match parent時,viewgroup會將其設定為exactl...

ViewGroup 自定義控制項

自定義viewgroup這篇文章是針對自定義layoutmanager來寫的,提取出相關自定義的相同點。所有的自定義都可以歸結為在父控制項裡面放置子控制項。一 繼承類 viewgroup 繼承之後需要實現構造,由於一般是在xml中引入所有需要實現以下構造 viewgroup context cont...

自定義ViewGroup 回顧

自定viewgroup要比自定義view要複雜一點,因為自定義viewgroup不僅測量自身還要測量子元素和及重寫onlayout 來一次排列子view。下面這篇文章是關於自定義viewgroup的一些基本知識,這些主要內容來自 android開發藝術探索 在文章最後又這本書的網上版本。viewgr...