結(jié)論:android中從同一個(gè)資源文件中加載出來(lái)的drawable會(huì)共享狀態(tài),如果有加載出來(lá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中加載出來(lái)的(包括矢量圖、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)出和原來(lái)第二個(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的各派生類(lèi)實(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)
}
}
}