android Drawable - getConstantState.newDrawable() vs mutate()

2022-09-02 21:23:26

在android中,我读过一些关于可绘制对象如何共享恒定状态的文章。因此,如果对可绘制对象进行更改,则会影响所有相同的位图。例如,假设您有一个星形可绘制对象列表。改变一个上的阿尔法将改变所有的星星可绘制阿尔法。但是您可以使用mutate来获取没有共享状态的可绘制副本。
我正在阅读的文章在这里

现在进入我的问题:

Android中的以下两个调用有什么区别:

Drawable clone = drawable.getConstantState().newDrawable();

// vs

Drawable clone = (Drawable) drawable.getDrawable().mutate();

对我来说,他们都在克隆一个可绘制对象,因为它们都返回一个没有共享状态的可绘制对象。我错过了什么吗?


答案 1

正如@4castle注释中指出的那样,方法返回具有复制的常量可绘制状态的可绘制对象的相同实例。文档说mutate()

可变可绘制对象保证不会与任何其他可绘制对象共享其状态

因此,在不影响具有相同状态的可绘制对象的情况下更改可绘制对象是安全的

让我们玩这个可画 - 黑色形状

 <!-- shape.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="@android:color/black" />
</shape>


view1.setBackgroundResource(R.drawable.shape); // set black shape as a background
view1.getBackground().mutate().setTint(Color.CYAN); // change black to cyan
view2.setBackgroundResource(R.drawable.shape); // set black shape background to second view


相反的方法是 。它将创建一个新的可绘制对象,但具有相同的常量状态。例如,查看:newDrawable()BitmapDrawable.BitmapState

    @Override
    public Drawable newDrawable() {
        return new BitmapDrawable(this, null);
    }

对新可绘制对象的更改不会影响当前可绘制对象,但会更改状态:

view1.setBackgroundResource(R.drawable.shape); // set black shape as background
Drawable drawable = view1.getBackground().getConstantState().newDrawable();
drawable.setTint(Color.CYAN); // view still black
view1.setBackground(drawable); // now view is cyan
view2.setBackgroundResource(R.drawable.shape); // second view is cyan also

答案 2

推荐