Search code examples
androiddrawableandroid-drawableandroid-resourcesandroid-vectordrawable

Android: Tint one of three icons


I need 3 icons: ContextCompat.getDrawable(this, R.drawable.my_vector_drawable).

First – without tint, second – with tint, third – without tint too,

Ok.

        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);

Where R.drawable.my_vector_drawable is white figure.

But as result – 3 icons with tint (WHY?!).

For example, I tried to set ContextCompat.getColor(this, R.color.somecolor), and result is... Two icons with tint! Icon 2 and 3, and first icon – without tint (Why?!)

How to load NOT cached drawable? Or how to fix this issue? AppCompat 23.4.+


Solution

  • You have to mutate() your drawables.

    Now you refer to the exact same source. As soon as you mutate your drawable, each one will have its own state.

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

    From 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.