DrawableCompat setTint 为所有具有相同 id 的新 Drawable 着色

DrawableCompat setTint tints all new Drawables with the same id

我有聊天气泡,我想在某些情况下对其进行着色:

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

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

问题是,一旦R.drawable.bg_chat_bubble(它是一个 9 补丁)被着色,然后所有调用 ContextCompat.getDrawable(context, R.drawable.bg_chat_bubble) returns 着色图像而不是原始图像。即使当我关闭聊天并打开完全不同的聊天时,那里的气泡仍具有以前的色调。只有杀死应用程序才能帮助恢复正确的颜色。直到第一次染色...

即使在调用 setTint 后直接在 tint 分支中设置 bubbleDrawable = ContextCompat.getDrawable(context, R.drawable.bg_chat_bubble) 也会给出着色图像而不是原始图像。

我也试过getResources().getDrawable(R.drawable.bg_chat_bubble)但结果是一样的。因此,一旦我想为任何可绘制资源使用色调,我必须始终为该资源设置色调,否则我会得到不可预知的结果。

这发生在 Android 5.1(可能还有其他)以及 appcompat-v7:23.2.+appcompat-v7:23.1.+。这是已知错误还是我做错了什么?

您只需要在设置色调之前改变您的可绘制对象即可:

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.