DrawableCompat setTint对具有相同id的所有新Drawable进行着色

时间:2016-03-29 09:08:02

标签: android android-appcompat android-drawable tint

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

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)的所有调用都会返回有色图像而不是原始图像。即使我关闭聊天并打开完全不同的聊天,那里的气泡也有之前的色彩。只有杀死应用程序才有助于恢复正确的颜色。直到第一个色调...

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

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

这种情况发生在Android 5.1(可能还有其他人)以及appcompat-v7:23.2.+appcompat-v7:23.1.+上。这是一个知道错误还是我做错了什么?

1 个答案:

答案 0 :(得分:28)

你需要的是在设置色调之前改变你的drawable:

bubbleDrawable.mutate()

Drawable.mutate

  

使这个drawable可变。此操作无法逆转。一个   可变的drawable保证不与任何其他人共享其状态   绘制。当您需要修改属性时,这尤其有用   从资源加载的drawables。默认情况下,所有drawables   从同一资源加载的实例共享一个公共状态;如果你   修改一个实例的状态,所有其他实例将接收   同样的修改。在一个可变的Drawable上调用这个方法会   没有效果。