Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DrawableCompat setTint tints all new Drawables with the same id

I have chat bubbles which I want to tint in some situations:

Drawable bubbleDrawable = ContextCompat.getDrawable(context, R.drawable.bg_chat_bubble);

if (tint) {
    bubbleDrawable = DrawableCompat.wrap(bubbleDrawable);
    DrawableCompat.setTint(bubbleDrawable, bubbleTint);
}

The problem is that once once that R.drawable.bg_chat_bubble (it is a 9-patch) was tinted then all calls to ContextCompat.getDrawable(context, R.drawable.bg_chat_bubble) returns the tinted image instead of the orignal. Even when I close a chat and open completely different chat, the bubbles there have the previous tint. Only killing the app helps to restore the correct color. Until the first tint...

Even directly setting the bubbleDrawable = ContextCompat.getDrawable(context, R.drawable.bg_chat_bubble) inside the tint branch after calling setTint gives a tinted image instead of the original.

I also tried getResources().getDrawable(R.drawable.bg_chat_bubble) but the result is the same. So once I want to use a tint for any drawable resrouce I must always set a tint for that resource otherwise I get unpredictable results.

This is happening on Android 5.1 (probably also others) and with appcompat-v7:23.2.+ and appcompat-v7:23.1.+. Is this a know bug or I am doing something wrong?

like image 360
shelll Avatar asked Mar 29 '16 09:03

shelll


1 Answers

all you need is to mutate your drawable before setting the tint:

bubbleDrawable.mutate()

Drawable.mutate

Make this drawable mutable. This operation cannot be reversed. A mutable drawable is guaranteed to not share its state with any other drawable. This is especially useful when you need to modify properties of drawables loaded from resources. By default, all drawables instances loaded from the same resource share a common state; if you modify the state of one instance, all the other instances will receive the same modification. Calling this method on a mutable Drawable will have no effect.

like image 183
pskink Avatar answered Sep 30 '22 17:09

pskink