Android:为三个图标之一着色

Android: Tint one of three icons

我需要 3 个图标:ContextCompat.getDrawable(this, R.drawable.my_vector_drawable)

第一个 – 没有染色,第二个 – 有染色,第三个 – 没有染色,

好的。

        ImageView img1 = (ImageView) findViewById(R.id.img1);
        ImageView img2 = (ImageView) findViewById(R.id.img2);
        ImageView img3 = (ImageView) findViewById(R.id.img3);

        Drawable drawable1 = ContextCompat.getDrawable(this, R.drawable.my_vector_drawable);

        Drawable drawable2 = DrawableCompat.wrap(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));
        DrawableCompat.setTintMode(drawable2, PorterDuff.Mode.MULTIPLY);
        DrawableCompat.setTintList(drawable2, ContextCompat.getColorStateList(this, R.color.menu_tint_colors));

        Drawable drawable3 = ContextCompat.getDrawable(this, R.drawable.my_vector_drawable);

        img1.setImageDrawable(drawable1);
        img2.setImageDrawable(drawable2);
        img3.setImageDrawable(drawable3);

其中R.drawable.my_vector_drawable为白色图形

但结果 – 3 个带有色调的图标(为什么?!)。

例如,我尝试设置ContextCompat.getColor(this, R.color.somecolor),结果是...两个带有色调的图标!图标 2 和 3,以及第一个图标 – 没有色调(为什么?!)

如何加载未缓存的可绘制对象?或者如何解决这个问题?应用程序兼容性 23.4.+

您必须 mutate() 您的可绘制对象。

现在您指的是完全相同的来源。一旦你改变了你的可绘制对象,每一个都会有自己的状态。

Drawable d = ContextCompat.getDrawable(this, R.drawable.my_vector_drawable).mutate();

来自docs

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.

@azizbekian 的回答是正确的,但在某些情况下,对每个可绘制对象都这样做可能效率低下。查看 this answer 了解更多详情。

我建议使用 TintedIconCache instead of mutating your drawables. It will manage a cache for your tinted drawables so that they are only created once when needed, and then cached in a memory efficient way for subsequent usage. It is a single class an you can grab from this gist

用法

// Get an instance
final TintedIconCache cache = TintedIconCache.getInstance();

// Will be fetched from the resources
Drawable backIcon = cache.fetchTintedIcon(context, R.drawable.icon, R.color.black));

// Will be fetched from the resources as well
Drawable bleuIcon = cache.fetchTintedIcon(context, R.drawable.icon, R.color.bleu));
   
// Will be fetched from the cache, with no mutation!!!
Drawable backIconTwo = cache.fetchTintedIcon(context, R.drawable.icon, R.color.back));