最近在開發過程中遇到一個bug:我在一個recyclerview的onScrolled回調中改變另一個獨立view的背景透明值,從而實現比較友好的交互效果。代碼如下:
`mSearchViewLayout.getBackground().setAlpha(alpha);`
透明色的漸變功能沒有問題,但是發現一個奇怪的現象,recyclerview的列表項的背景色變成了F8F8F8,而這個顏色我們代碼中并不存在,debug發現,每次改變mSearchViewLayout的alpha值時,列表項的background alpha也會同步改變,然而這兩個view并不想關,也沒有事件聯系。再次debug可以發現,兩個view的背景都是純白的ColorDrawable,并且ColorDrawable的mColorState類屬性是同一個對象,原來是cache導致改變其中一個alpha為0時,另一個也同步更新,導致列表項顯示的是rootview的默認顏色F8F8F8。查閱源碼:
最終執行
可以發現有ConstantState的緩存Map,也就是復用了這個ConstantState,所以在一處改變,只要顏色相同的view也會隨著改變。
說完來龍去脈,接下來說解決方法,google使用了緩存提升性能和效率當然也會考慮到這一點,ColorDrawable中有個mutate方法:
類似于克隆,讓ColorDrawable重新持有一個新的ConstantState對象,并且不會重復創建。因為這個ConstantState對象不會被cache,新建的對象就不會對其他view產生影響。