結(jié)論:android中從同一個(gè)資源文件中加載出來的drawable會(huì)共享狀態(tài)瘟芝,如果有加載出來多個(gè)drawable的實(shí)例對(duì)象琐簇,當(dāng)改變了其中一個(gè)的狀態(tài)時(shí),其他drawable的狀態(tài)也會(huì)相應(yīng)改變究西。
實(shí)例:在修改一個(gè)view卦碾,或者它的background,即時(shí)是新創(chuàng)建的view對(duì)象渤早,如果它是從同一個(gè)xml中加載出來的(包括矢量圖职车、shape等),在代碼中動(dòng)態(tài)修改的它顏色鹊杖,會(huì)影響到其他從該xml加載出的view悴灵。這是因?yàn)樗膍GradientState是被復(fù)用的。
下面兩個(gè)圖骂蓖,是從同一個(gè)xml中加載的view對(duì)象(在recyclerView的兩個(gè)item中)积瞒,在動(dòng)態(tài)改變了第二個(gè)view的background顏色后,如果第一個(gè)view所在的item重新bind登下,新創(chuàng)建出的view茫孔,也表現(xiàn)出和原來第二個(gè)view同樣的背景顏色。修改顏色的方法如下:
private fun changeBackgroundColor(@ColorInt argb: Int?) {
argb?.let {
if (mRootView?.background is GradientDrawable) {
val grad: GradientDrawable = mRootView?.background as GradientDrawable
grad.setColor(argb)
}
}
}
--
可以看到庐船,這個(gè)兩個(gè)view的background對(duì)象银酬,確實(shí)是兩個(gè)不同的對(duì)象,但是他們的mGradientState筐钟,是同一個(gè)GradientState對(duì)象揩瞪,這里發(fā)生了復(fù)用。
所以篓冲,在動(dòng)態(tài)修改drawable的顏色(或者GradientState中其他屬性)時(shí)李破,需要將改該drawable設(shè)置為mutate狀態(tài),即調(diào)用mutate()方法壹将,該方法會(huì)為drawable創(chuàng)建新的mGradientState(Drawable的各派生類實(shí)現(xiàn)有所不同)嗤攻。舉例如下:GradientDrawable.mutate()方法如下:
所以需要將上述修改背景顏色的方法,修改如下:
private fun changeBackgroundColor(@ColorInt argb: Int?) {
argb?.let {
if (mRootView?.background is GradientDrawable) {
val grad: GradientDrawable = (mRootView?.background as GradientDrawable).mutate() as GradientDrawable
grad.setColor(argb)
}
}
}