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

in android, I read several articles on how drawables share persistent state. therefore, if you make changes to drawable, it affects all the same bitmap images. for example, let's say you have a list of star drawings. changing alpha on one will change all star alpha characters. but you can use mutate to get your own copy with non-shared migration option.
The article I read is here

Now to my question:

What is the difference between two calls in android:

Drawable clone = drawable.getConstantState().newDrawable(); // vs Drawable clone = (Drawable) drawable.getDrawable().mutate(); 

For me, they both clone drawable, as they both return a drawable that has no common state. Did I miss something?

+6
source share
1 answer

As @ 4castle pointed out in the mutate() comments, the method returns the same instance of the object with the ability to copy with the copied constant hardy state. Documents say that

A mutable copyable property cannot share its state with any other available

In this way, you can safely change callouts without affecting drawings with the same state.

Play with this drawable - 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() . He creates a new affordable, but with the same constant state. For instance. take a look at BitmapDrawable.BitmapState :

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

Changes in the new drawable will not affect the current drawable, but they will change the 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 
+5
source

Source: https://habr.com/ru/post/1013170/


All Articles