Drawable Cache引起的背景连锁改变问题

作者: 恶魔殿下_HIM | 来源:发表于2017-07-20 14:07 被阅读141次

    最近在开发过程中遇到一个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。查阅源码:

    http://guard.pt.miui.com/opengrok2/xref/v8-m-cancro-alpha/frameworks/base/core/java/android/content/res/Resources.java#813

    最终执行

    http://guard.pt.miui.com/opengrok2/xref/v8-m-cancro-alpha/frameworks/base/core/java/android/content/res/Resources.java#2528

    可以发现有ConstantState的缓存Map,也就是复用了这个ConstantState,所以在一处改变,只要颜色相同的view也会随着改变。

    说完来龙去脉,接下来说解决方法,google使用了缓存提升性能和效率当然也会考虑到这一点,ColorDrawable中有个mutate方法:

    http://guard.pt.miui.com/opengrok2/xref/v8-m-cancro-alpha/frameworks/base/graphics/java/android/graphics/drawable/ColorDrawable.java#84

    类似于克隆,让ColorDrawable重新持有一个新的ConstantState对象,并且不会重复创建。因为这个ConstantState对象不会被cache,新建的对象就不会对其他view产生影响。

    相关文章

      网友评论

        本文标题:Drawable Cache引起的背景连锁改变问题

        本文链接:https://www.haomeiwen.com/subject/ylgdkxtx.html