571

Need to set tint for an image view... I am using it the following way:

imageView.setColorFilter(R.color.blue,android.graphics.PorterDuff.Mode.MULTIPLY);

But it doesn't change...

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416
  • 17
    You may have used the integer resource id instead of integer color value, try to convert R.color.blue to getResources().getColor(R.color.blue) – milosmns May 19 '15 at 16:29
  • Drawable drawable = ... ; drawable.setColorFilter(ContextCompat.getColor(context, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable(drawable); // any color can be used here – flame3 May 21 '18 at 11:05

29 Answers29

1250

UPDATE:
@ADev has newer solution in his answer here, but his solution requires newer support library - 25.4.0 or above.


You can change the tint, quite easily in code via:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

If you want color tint then

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.MULTIPLY);

For Vector Drawable

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.SRC_IN);
Aphex
  • 7,390
  • 5
  • 33
  • 54
Hardik
  • 17,179
  • 2
  • 35
  • 40
  • 2
    More Information: [public final void setColorFilter (int color, PorterDuff.Mode mode)](http://developer.android.com/reference/android/widget/ImageView.html#setColorFilter%28int%2C%20android.graphics.PorterDuff.Mode%29) – Jon May 29 '15 at 16:36
  • 14
    In xml, android:tint="@color/blue" – Luis Mar 17 '16 at 15:02
  • 1
    android:tint="@color/blue" does not work while loading image via Glide. – Tasneem Dec 14 '16 at 08:35
  • i am using this code but it takin lot of time to set the color on image – Sarbjyot Dec 19 '16 at 09:39
  • 1
    Plus android:tint is 21+ – androidguy Mar 17 '17 at 05:43
  • 9
    `android:tint` works on all android versions. Maybe you're talking about `drawableTint`? – finstas Apr 20 '17 at 11:10
  • @finstas the question was how to set tint programmatically not from xml. Read more: https://developer.android.com/reference/android/widget/ImageView.html#setImageTintList(android.content.res.ColorStateList) – Hardik Apr 24 '17 at 06:28
  • @Hardik sorry, the reply was intended for user3175580's reply where he was talking about the xml-part – finstas Apr 26 '17 at 14:43
  • 21
    PorterDuff.Mode.MULTIPLY doesn't work in my situation i used PorterDuff.Mode.SRC_IN and it works – Mohamed Nageh Sep 26 '17 at 11:13
  • The same situation to @mohnage7. PorterDuff.Mode.MULTIPLY doesn't work for vector drawable in Android 8 for me, but PorterDuff.Mode.SRC_IN works. – Pavlo28 Oct 24 '17 at 20:42
  • The same situation to @mohnage7. PorterDuff.Mode.MULTIPLY doesn't work for vector drawable in Android 6.0.1 MXB48T for me, but PorterDuff.Mode.SRC_IN works. – Francis Bacon Oct 25 '17 at 06:40
  • 1
    I faced with an interesting problem. Although I am using the methods described above, it does not work on Samsung Note 3 device. Then I figure out an interesting case : When initial tint color is given from xml, it cannot be changed dynamically with these methods. Solution is quite simple, I just remove tint attribute from xml and set initial tint color also dynamically and cheers.. Hope this saves a few minutes for others :) – Erdem Dec 01 '17 at 08:12
  • Was trying to tint an `ImageButton` which had png image in it with `DrawableCompat.setTint(v.getDrawable(), ContextCompat.getColor(getContext(), R.color.gold));` which didn't work on API 19, but this did: `v.setColorFilter(ContextCompat.getColor(getContext(), R.color.gold), android.graphics.PorterDuff.Mode.SRC_IN);` – Starwave Jan 16 '18 at 11:14
  • Your update should have referenced my answer since that's where you got it from: https://stackoverflow.com/a/45571812/7399050 – ADev Feb 14 '18 at 13:12
  • 1
    @ADev of course but you haven't mention it properly in your answer that your solution is new and require newer support library 25.4.0 and above because with lower version of support lib this class is not available so no one could find it !!!! by the way i edited the answer :) good day... – Hardik Feb 14 '18 at 14:48
  • it works perfectly fine except for Data Binding + Lenovo A7000-a + VectorDrawable T_T – ericn Apr 19 '18 at 10:40
  • ImageView imageViewIcon = (ImageView) listItem.findViewById(R.id.imageViewIcon); imageViewIcon.setColorFilter(getContext().getResources().getColor(R.color.blue)); – Vikash Sharma Jul 03 '18 at 11:24
  • 1
    This method does not work if the tint is set via XML. Remove tint from XML and set via this method programmatically. – Ray Li Feb 13 '19 at 16:39
396

Most answers refer to using setColorFilter which is not what was originally asked.

The user @Tad has his answer in the right direction but it only works on API 21+.

To set the tint on all Android versions, use the ImageViewCompat:

ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(yourTint));

Note that yourTint in this case must be a "color int". If you have a color resource like R.color.blue, you need to load the color int first:

ContextCompat.getColor(context, R.color.blue);
ADev
  • 5,259
  • 2
  • 16
  • 29
  • 13
    Should be the accepted answer. Note that it works only on xml `ImageView` instances with AppCompat theme or on `AppCompatImageView` subclasses. – Louis CAD Nov 10 '17 at 13:00
  • 1
    @ADev appreciate your solution but the question was asked in 2013 and ImageViewCompat and AppCompatImageView release with v4 support lib 25.4.0 in June 2017 and 25.1.0 December 2016 respectively :) – Hardik Jan 27 '18 at 08:22
  • 1
    @ADev of course but you haven't mention it properly in your answer that your solution is new and require newer support library 25.4.0 and above because with lower version of support lib this class is not available so no one could find it !!!! by the way i edited the answer :) good day... – Hardik Feb 14 '18 at 14:20
77

This worked for me

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));
Etienne Lawlor
  • 6,817
  • 18
  • 77
  • 89
39

@Hardik has it right. The other error in your code is when you reference your XML-defined color. You passed only the id to the setColorFilter method, when you should use the ID to locate the color resource, and pass the resource to the setColorFilter method. Rewriting your original code below.

If this line is within your activity:

imageView.setColorFilter(getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

Else, you need to reference your main activity:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

Note that this is also true of the other types of resources, such as integers, bools, dimensions, etc. Except for string, for which you can directly use getString() in your Activity without the need to first call getResources() (don't ask me why).

Otherwise, your code looks good. (Though I haven't investigated the setColorFilter method too much...)

CrepeGoat
  • 2,315
  • 20
  • 24
33

Better simplified extension function thanks to ADev

fun ImageView.setTint(@ColorRes colorRes: Int) {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, colorRes)))
}

Usage:-

imageView.setTint(R.color.tintColor)
Manohar
  • 22,116
  • 9
  • 108
  • 144
  • Is there a similar one for the Button's/TextView's text tint? – android developer Jul 18 '19 at 14:14
  • do you mean textview text color or tint for textview drawable ? – Manohar Jul 19 '19 at 04:04
  • I mean "text tint". The color of the text. But I think it's quite problematic, as text has a color for each state... Then again, how come it works fine for when I set accent color ... Odd.... Is it possible perhaps to set the accent color to a specific Button (or TextView) , programmatically ? – android developer Jul 20 '19 at 09:47
25

After i tried all methods and they did not work for me.

I get the solution by using another PortDuff.MODE.

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);
Catluc
  • 1,775
  • 17
  • 25
25

If your color has hex transparency, use the below code.

ImageViewCompat.setImageTintMode(imageView, PorterDuff.Mode.SRC_ATOP);
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(Color.parseColor("#80000000")));

To clear the tint

ImageViewCompat.setImageTintList(imageView, null);
David
  • 3,971
  • 1
  • 26
  • 65
Sai
  • 15,188
  • 20
  • 81
  • 121
17

Beginning with Lollipop, there is also a tint method for BitmapDrawables that works with the new Palette class:

public void setTintList (ColorStateList tint)

and

public void setTintMode (PorterDuff.Mode tintMode)

On older versions of Android, you can now use the DrawableCompat library

Tad
  • 4,668
  • 34
  • 35
17

Simple and one line

imageView.setColorFilter(activity.getResources().getColor(R.color.your_color));
Gautam Surani
  • 1,136
  • 10
  • 21
14

Try this. It should work on all Android versions that the support library supports:

public static Drawable getTintedDrawableOfColorResId(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorRes int colorResId) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), ContextCompat.getColor(context, colorResId));
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorInt int color) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), color);
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, PorterDuff.Mode.SRC_IN);
    return wrapDrawable;
}

You can use any of the above to make it work.

You can read about more interesting features of DrawableCompat on the docs, here.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
14

Kotlin solution using extension function, to set and unset the tinting :

fun ImageView.setTint(@ColorInt color: Int?) {
    if (color == null) {
        ImageViewCompat.setImageTintList(this, null)
        return
    }
    ImageViewCompat.setImageTintMode(this, PorterDuff.Mode.SRC_ATOP)
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
}
android developer
  • 114,585
  • 152
  • 739
  • 1,270
13

For set tint for an image view programmatically in android

I have two methods for android :

1)

imgView.setColorFilter(context.getResources().getColor(R.color.blue));

2)

 DrawableCompat.setTint(imgView.getDrawable(),
                     ContextCompat.getColor(context, R.color.blue));

I hope I helped anyone out :-)

Abhign01
  • 311
  • 4
  • 4
12

I found that we can use color selector for tint attr:

mImageView.setEnabled(true);

activity_main.xml:

<ImageView
    android:id="@+id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_arrowup"
    android:tint="@color/section_arrowup_color" />

section_arrowup_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_enabled="true"/>
    <item android:color="@android:color/black" android:state_enabled="false"/>
    <item android:color="@android:color/white"/>
</selector>
NickUnuchek
  • 11,794
  • 12
  • 98
  • 138
  • Hi, It's not working for vector drawables..Any workaround for same? – Manukumar Aug 28 '18 at 12:46
  • @Manukumar Use `app:srcCompat` instead of `android:src` , and add `vectorDrawables.useSupportLibrary = true` into the `defaultConfig` part of your build.gradle file. Tested to work fine on Kitkat emulator. – android developer Jan 15 '19 at 10:10
  • As per [Android docs](https://developer.android.com/guide/topics/resources/color-list-resource), I've created a subdirectory _color_ in the _res_ directory to store the file section_arrowup_color.xml. Android Studio will help you create new files if you right click on the _color_ subdirectory, select _new_ and then _Color Resource File_. – user3622622 Apr 04 '21 at 22:40
10

Adding to ADev's answer (which in my opinion is the most correct), since the widespread adoption of Kotlin, and its useful extension functions:

fun ImageView.setTint(context: Context, @ColorRes colorId: Int) {
    val color = ContextCompat.getColor(context, colorId)
    val colorStateList = ColorStateList.valueOf(color)
    ImageViewCompat.setImageTintList(this, colorStateList)
}

I think this is a function which could be useful to have in any Android project!

Cillian Myles
  • 696
  • 8
  • 16
10

An extension function in kotlin, to set and unset the tinting.

fun ImageView.setTint(@ColorRes color: Int?) {
  if (color == null) {
    ImageViewCompat.setImageTintList(this, null)
  } else {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, color)))
}}

Usage: yourImageView.setTint(R.color.white) for setting and for removing just: yourImageView.setTint(null)

Liridon Sadiku
  • 309
  • 3
  • 7
9

As the first answer didn't work for me:

//get ImageView
ImageView myImageView = (ImageView) findViewById(R.id.iv);

//colorid is the id of a color defined in values/colors.xml
myImageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorid)));

This only seems to work in API 21+, but for me that wasn't an issue. You can use an ImageViewCompat to resolve that issue, tho.

I hope I helped anyone out :-)

Felix
  • 824
  • 8
  • 21
8

Beginning in Lollipop, there is a method called ImageView#setImageTintList() that you can use... the advantage being that it takes a ColorStateList as opposed to just a single color, thus making the image's tint state-aware.

On pre-Lollipop devices, you can get the same behavior by tinting the drawable and then setting it as the ImageView's image drawable:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);
Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
6
Random random=new Random;
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
ColorFilter cf = new PorterDuffColorFilter(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)),Mode.OVERLAY);

imageView.setImageResource(R.drawable.ic_bg_box);
imageView.setColorFilter(cf);
Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
Pawan asati
  • 292
  • 2
  • 13
3

As @milosmns said, you should use imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

This API need color value instead of color resource id, That's the root cause why your statement didn't work.

HunkD
  • 76
  • 2
3

Don't use PoterDuff.Mode, Use setColorFilter() it works for all.

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));
c-an
  • 3,543
  • 5
  • 35
  • 82
Vikash Sharma
  • 539
  • 8
  • 13
3

In case you want to set selector to your tint:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));
Yusril Maulidan Raji
  • 1,682
  • 1
  • 21
  • 46
2

I am late in the party but I didn't see my solusion above. We are able to set tint color via setImageResource(), too (my minSdkVersion is 24).

So, first, you need to create a selector and save it in /drawable asset folder (I call it ic_color_white_green_search.xml)

<!-- Focused and not pressed -->
<item android:state_focused="true"
      android:state_pressed="false">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Focused and pressed -->
<item android:state_focused="true"
      android:state_pressed="true">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Default -->
<item android:drawable="@drawable/ic_search"/>

Then set it in code like this:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)
Hesam
  • 52,260
  • 74
  • 224
  • 365
2

For me this code works. I use it with card and image views but i thins it works in any view to change their tints colors. cardBookmark is my cardView.

var cardDrawable: Drawable = binding.cardBookmark.background
cardDrawable = DrawableCompat.wrap(cardDrawable)
DrawableCompat.setTint(cardDrawable, resources.getColor(R.color.shuffleColor))
binding.cardBookmark.background = cardDrawable
Anorov Hasan
  • 123
  • 2
  • 2
2

In java I'm using

imageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(context, R.color.red)));
Ujjwal Jung Thapa
  • 604
  • 2
  • 8
  • 31
1

Disclaimer: This is not the answer for this post. But it is the answer for this question i.e. how to reset the color/tint of the drawable or imageview. Sorry, for putting this over here as that question is not accepting answers and referring to this post for answers. So, adding it here so that someone looking for a solution might look end up at this.

As mentioned by @RRGT19 in the comment of this answer. We can reset the color using setImageTintList() and passing null as the tintList. It worked magically for me.

ImageViewCompat.setImageTintList(imageView, null)
Adarsh Srivastava
  • 456
  • 1
  • 5
  • 13
0

if you are changing tint on Focus change then try this please

DrawableCompat.setTint(imgView.getDrawable(),
                 ContextCompat.getColor(context, R.color.blue));
harry
  • 171
  • 1
  • 4
0

After I tried all methods and they did not work for me.

I get the solution specially in case if you are changing the color through any colorPicker library which returns an Integer value of selectedColor.

widgetIcon is my ImageView and selectedColor is the color from colorPicker

var imageDrawable: Drawable = widgetIcon.background
        imageDrawable = DrawableCompat.wrap(imageDrawable)
        DrawableCompat.setTint(imageDrawable, selectedColor)
        widgetIcon.background = imageDrawable
Annas Bin Waheed
  • 291
  • 1
  • 4
  • 12
0

I did below:

view.drawable.setTint(ContextCompat.getColor(requireContext(),R.color.color_05F73F))
Codemaker2015
  • 12,190
  • 6
  • 97
  • 81
-4

Not exact answer but a simpler alternative:

  • Place another view on top of the image
  • Change the alpha value of the view however you want (programmatically) to get the desired effect.

Here is a snippet for that:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:contentDescription="@string/my_description"
        android:scaleType="fitXY"
        android:src="@drawable/my_awesome_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:alpha="0.5"
        android:background="@color/my_blue_color"/>
</FrameLayout>
Shubham Chaudhary
  • 47,722
  • 9
  • 78
  • 80
  • this is about tint! not alpha that is for transparency. – David Jan 28 '16 at 09:47
  • But that ends up acting as a tint. You should try it yourself. This is just one way to look at things. – Shubham Chaudhary Jan 28 '16 at 13:15
  • @ShubhamChaudhary I know this is late but what if the image is `png`. Then won't the background change? Also Alpha and tint are very different. Tint Is like color replacement, if I am not wrong. No offence intended. Just trying to help :) – KISHORE_ZE Jun 13 '16 at 18:46
  • Valid point. This answer helped in my case. Hope fits someone else's shoes too. – Shubham Chaudhary Jun 13 '16 at 19:11