36

I have an ImageView. In its onClick I get its Drawable:

Drawable dr = ((ImageView) v).getDrawable();

And set it to a dialog's ImageView:

zoomedImage.setImageDrawable(dr);

But when I close the dialog or the activity is resumed. The image at the original position gets stretched and is shown larger than its size, leading to only a portion of the image is visible in the ImageView.

Is this a case of deep copy or there is another problem? If it is, how can do I deep copy the original Drawable so that I could set the copy to zoomed image?

Thanks in advance.

frostman
  • 566
  • 2
  • 12
  • 25
Shashank Degloorkar
  • 3,151
  • 4
  • 32
  • 50

4 Answers4

89

Finally I succeed! I had similar problem, when I used color filter on my drawable it changed the drawable, its very close to the solution of the other people here, but only this worked for me:

Drawable drwNewCopy = dr.getConstantState().newDrawable().mutate();
LiranNis
  • 1,184
  • 1
  • 12
  • 14
  • 6
    FINALLY! This is the solution to create an autonomous copy of a drawable. To mutate() the orginal drawable is not a good solution, it does not always work. Creating a new copy from the cache of the drawable (i.e. the getContantState()) works. This comment FYI for others that have spent hours upon hours on this immature/nonfinished api. – carl Dec 13 '16 at 10:23
  • 2
    extension for Kotlin : fun Drawable.copy() = constantState?.newDrawable()?.mutate() – Filipkowicz Aug 02 '19 at 07:33
  • If I use the same `Drawable` on many views, is it better to copy like that or to get it again from resource? – Thomas Mar 10 '21 at 13:24
22

I managed to copy the drawable using following code:

drawable.mutate().getConstantState().newDrawable();

Here mutate() makes the drawable mutable to avoid sharing its state, and getConstantState().newDrawable() creates a new copy.

Thus different ImageViews use different drawables and there's no stretching.

ernazm
  • 9,208
  • 4
  • 44
  • 51
1

Use BitmapFactory to convert the drawable into bitmap separately make or perform changes on it.

Just Variable
  • 892
  • 10
  • 19
0

The above solutions won't work for me, But it works

val myDrawable = DrawableCompat.wrap(view.background).mutate() as GradientDrawable
myDrawable.setColor(ContextCompat.getColor(view.context, R.color.White))
TOUSIF
  • 285
  • 5
  • 4