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

倾然丶 夕夏残阳落幕 提交于 2021-01-21 12:32:11

问题


in android i have read a few articles on how drawables share a constant state. so if you make a change to a drawable it affects all the same bitmaps. for example lets say you had a list of star drawables. changing the alpha on one will change all the star drawables alpha. but you can use mutate to get your own copy of a drawable with no shared state.
The article i was reading is here

Now onto my question:

What is the difference between the following two calls in android:

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

// vs

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

For me they are both cloning a drawable as they both return a drawable that has no shared state. Am i missing something ?


回答1:


As @4castle pointed in comments mutate() method returns same instance of the drawable with copied constant drawable state. Docs says that

A mutable drawable is guaranteed to not share its state with any other drawable

So it is safe to change a drawable without affecting drawables with the same state

Lets play with this drawable - a black shape

 <!-- 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


The opposite method is newDrawable(). It creates a new drawable but with the same constant state. E.g. look at BitmapDrawable.BitmapState:

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

Changes to new drawable will not affect current drawable, but will change a state:

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


来源:https://stackoverflow.com/questions/41156790/android-drawable-getconstantstate-newdrawable-vs-mutate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!