Change drawable color programmatically

The question:

I’m trying to change the color on a white marker image by code. I have read that the code below should change the color, but my marker remains white.

Drawable.setColorFilter( 0xffff0000, Mode.MULTIPLY )

Did I miss something? Is there any other way to change colors on my drawables located in my res folder?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Try this:

Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, R.drawable.my_drawable); 
Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
DrawableCompat.setTint(wrappedDrawable, Color.RED);    

Using DrawableCompat is important because it provides backwards compatibility and bug fixes on API 22 devices and earlier.

Method 2

You can try this for svg vector drawable

DrawableCompat.setTint(
    DrawableCompat.wrap(myImageView.getDrawable()),
    ContextCompat.getColor(context, R.color.another_nice_color)
);

Method 3

You may need to call mutate() on the drawable or else all icons are affected.

Drawable icon = ContextCompat.getDrawable(getContext(), R.drawable.ic_my_icon).mutate();
TypedValue typedValue = new TypedValue();
getContext().getTheme().resolveAttribute(R.attr.colorIcon, typedValue, true);
icon.setColorFilter(typedValue.data, PorterDuff.Mode.SRC_ATOP);

Method 4

You can try this for ImageView. using setColorFilter().

imageView.setColorFilter(ContextCompat.getColor(context, R.color.colorWhite));

Method 5

Another way to do this on Lollipop, android 5.+ is setting a tint on a bitmap drawable like such:

<?xml version="1.0" encoding="utf-8"?>
<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_back"
    android:tint="@color/red_tint"/>

This will work for you if you have a limited number of colors you want to use on your drawables. Check out my blog post for more information.

Method 6

I have wrote a generic function in which you can pass context, icon is id drawable/mipmap image icon and new color which you need for that icon.

This function returns a drawable.

public static Drawable changeDrawableColor(Context context,int icon, int newColor) {
    Drawable mDrawable = ContextCompat.getDrawable(context, icon).mutate(); 
    mDrawable.setColorFilter(new PorterDuffColorFilter(newColor, PorterDuff.Mode.SRC_IN)); 
    return mDrawable;
} 

changeDrawableColor(getContext(),R.mipmap.ic_action_tune, Color.WHITE);

Method 7

You could try a ColorMatrixColorFilter, since your key color is white:

// Assuming "color" is your target color
float r = Color.red(color) / 255f;
float g = Color.green(color) / 255f;
float b = Color.blue(color) / 255f;

ColorMatrix cm = new ColorMatrix(new float[] {
        // Change red channel
        r, 0, 0, 0, 0,
        // Change green channel
        0, g, 0, 0, 0,
        // Change blue channel
        0, 0, b, 0, 0,
        // Keep alpha channel
        0, 0, 0, 1, 0,
});
ColorMatrixColorFilter cf = new ColorMatrixColorFilter(cm);
myDrawable.setColorFilter(cf);

Method 8

This worked for me. Make sure to put “ff” between 0x and color code. Like this 0xff2196F3

Drawable mDrawable = ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_vector_home);
                    mDrawable.setColorFilter(new
                            PorterDuffColorFilter(0xff2196F3,PorterDuff.Mode.SRC_IN));

Method 9

Same as the accepted answer but a simpler convenience method:

val myDrawable = ContextCompat.getDrawable(context, R.drawable.my_drawable)
myDrawable.setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_IN)
setCompoundDrawablesWithIntrinsicBounds(myDrawable, null, null, null)

Note, the code here is Kotlin.

Method 10

Use this: For java

view.getBackground().setColorFilter(Color.parseColor("#343434"), PorterDuff.Mode.SRC_OVER)

for Kotlin

view.background.setColorFilter(Color.parseColor("#343434"),PorterDuff.Mode.SRC_OVER)

you can use PorterDuff.Mode.SRC_ATOP, if your background has rounded corners etc.

Method 11

For those who use Kotlin a simple extension function:

fun Drawable.tint(context: Context,  @ColorRes color: Int) {
    DrawableCompat.setTint(this, context.resources.getColor(color, context.theme))
}

and then simply do

background.tint(context, R.color.colorPrimary)

Method 12

You may want to try Mode.LIGHTEN or Mode.DARKEN. The Android Javadocs are horrible at explaining what the PorterDuff Modes do. You can take a look at them here: PorterDuff | Android

I suggest looking around at Compositing on Mozilla’s site here. (They don’t have all the modes that android does but they have a lot of them)

Method 13

Syntax

"your image name".setColorFilter("your context".getResources().getColor("color name"));

Example

myImage.setColorFilter(mContext.getResources().getColor(R.color.deep_blue_new));

Method 14

You can change your drawable color in this way:

background = view.findViewById(R.id.background)

val uDrawable = AppCompatResources.getDrawable(view.context, R.drawable.background)
uDrawable?.let {
      val wDrawable = DrawableCompat.wrap(it)
      DrawableCompat.setTint(wDrawable, ContextCompat.getColor(view.context, 
                                                      color /*specify your int color code*/))
      background.background = wDrawable
}

Method 15

SDK >= 21 one line
myIconImageView.getDrawable().setTint(getResources().getColor(myColor))

Method 16

Kotlin Version

val unwrappedDrawable =
            AppCompatResources.getDrawable(this, R.drawable.your_drawable)
        val wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable!!)
DrawableCompat.setTint(wrappedDrawable, Color.RED)

Method 17

This is what i did:

public static Drawable changeDrawableColor(int drawableRes, int colorRes, Context context) {
    //Convert drawable res to bitmap
    final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), drawableRes);
    final Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth() - 1, bitmap.getHeight() - 1);
    final Paint p = new Paint();
    final Canvas canvas = new Canvas(resultBitmap);
    canvas.drawBitmap(resultBitmap, 0, 0, p);

    //Create new drawable based on bitmap
    final Drawable drawable = new BitmapDrawable(context.getResources(), resultBitmap);
    drawable.setColorFilter(new
            PorterDuffColorFilter(context.getResources().getColor(colorRes), PorterDuff.Mode.MULTIPLY));
    return drawable;
}

Method 18

Create Method like this :

//CHANGE ICON COLOR
private void changeIconColor(Context context ,int drawable){
    Drawable unwrappedDrawable = AppCompatResources.getDrawable(context, drawable);
    assert unwrappedDrawable != null;
    Drawable wrappedDrawable = DrawableCompat.wrap(unwrappedDrawable);
    DrawableCompat.setTint(wrappedDrawable, getResources().getColor(R.color.colorAccent));
}

and use it like it :

    changeIconColor(this,R.drawable.ic_home);

Method 19

Easiest Way to do it :

imageView.setColorFilter(Color.rgb(r, g b));

or

imageView.setColorFilter(Color.argb(a, r, g, b));

a, r, g, b : Color argb values.

Method 20

Long story short :

public void changeDrawableColor(Drawable drawable,int color){
    drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}

public Drawable getColoredDrawable(@DrawableRes int resid,int color){
    Drawable drawable= ContextCompat.getDrawable(context, resid).mutate();
    drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
    return drawable;
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment