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

she*_*lll 11 android tint android-appcompat android-drawable

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

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

if (tint) {
    bubbleDrawable = DrawableCompat.wrap(bubbleDrawable);
    DrawableCompat.setTint(bubbleDrawable, bubbleTint);
}
Run Code Online (Sandbox Code Playgroud)

问题是,一旦它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)但结果是一样的.因此,一旦我想为任何可绘制的resrouce使用色调,我必须始终为该资源设置一个色调,否则我会得到不可预测的结果.

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

psk*_*ink 32

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

bubbleDrawable.mutate()
Run Code Online (Sandbox Code Playgroud)

Drawable.mutate

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