Drawable共享状态问题

作者: Joe_blake | 来源:发表于2019-10-09 12:01 被阅读0次

    结论:android中从同一个资源文件中加载出来的drawable会共享状态,如果有加载出来多个drawable的实例对象,当改变了其中一个的状态时,其他drawable的状态也会相应改变。

    实例:在修改一个view,或者它的background,即时是新创建的view对象,如果它是从同一个xml中加载出来的(包括矢量图、shape等),在代码中动态修改的它颜色,会影响到其他从该xml加载出的view。这是因为它的mGradientState是被复用的。

    下面两个图,是从同一个xml中加载的view对象(在recyclerView的两个item中),在动态改变了第二个view的background颜色后,如果第一个view所在的item重新bind,新创建出的view,也表现出和原来第二个view同样的背景颜色。修改颜色的方法如下:

    private fun changeBackgroundColor(@ColorInt argb: Int?) {
            argb?.let {
                if (mRootView?.background is GradientDrawable) {
                    val grad: GradientDrawable = mRootView?.background as GradientDrawable
                    grad.setColor(argb)
                }
            }
        }
    
    View-1的background

    --

    View-2的background

    可以看到,这个两个view的background对象,确实是两个不同的对象,但是他们的mGradientState,是同一个GradientState对象,这里发生了复用。

    所以,在动态修改drawable的颜色(或者GradientState中其他属性)时,需要将改该drawable设置为mutate状态,即调用mutate()方法,该方法会为drawable创建新的mGradientState(Drawable的各派生类实现有所不同)。举例如下:GradientDrawable.mutate()方法如下:


    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)
                }
            }
        }
    

    相关文章

      网友评论

        本文标题:Drawable共享状态问题

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