Applying ColorFilter to ImageView with ShapedDrawable

84,399

Solution 1

Alright, I had a quick play with this and noticed your issue of the circles disappearing. Without you describing what exactly you tried, I assume you haven't tried setting the color filter to the Drawable itself yet? (as opposed to the ImageView, which only seems to work with BitmapDrawables).

The following statements work perfectly fine for an xml-declared ShapeDrawable with white as initial color:

ImageView redCircle = (ImageView) findViewById(R.id.circle_red_imageview);
ImageView greenCircle = (ImageView) findViewById(R.id.circle_green_imageview);
ImageView blueCircle = (ImageView) findViewById(R.id.circle_blue_imageview);

// we can create the color values in different ways:
redCircle.getDrawable().setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY );
greenCircle.getDrawable().setColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY );
blueCircle.getDrawable().setColorFilter(getResources().getColor(R.color.blue), PorterDuff.Mode.MULTIPLY );

The ShapeDrawable for completeness: (I set the size on the ImageView, see below)

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" >
    <solid android:color="@android:color/white" />
</shape>

And one of the ImageViews as example:

<ImageView
    android:id="@+id/circle_red_imageview"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:padding="5dp"
    android:src="@drawable/circle_white" />

Visual result:

Screenshot of colored circles

Solution 2

If you want to change Image Color use

PorterDuff.Mode.SRC_ATOP instead
PorterDuff.Mode.MULTIPLY

in above example.

Solution 3

You can use attribute android:tint in ImageView in xml.

Example:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/your_drawable"
    android:tint="@color/your_color" />

Tested on Android 4.1.2 and 6.0.1

Share:
84,399
aplavin
Author by

aplavin

Researcher at Russian Space Research Institute

Updated on August 06, 2022

Comments

  • aplavin
    aplavin almost 2 years

    I have an ImageView with android:src set to a ShapedDrawable, namely a white circle. What I want is to colorize this ImageView in runtime responding to some events. imgView.setColorFilter seems to be solution, but after using this (tried different parameters) the image becomes invisible (I don't see it at the screen).

    How to solve this? And are there better ways to have color circles?

  • Sufian
    Sufian over 10 years
    calling mutable() on the Drawable will help keep state of drawables.
  • Maurizio
    Maurizio almost 10 years
    Wow this just saved me, you definitely want to apply the filter to the Drawable and not simply the ImageView.
  • SadeepDarshana
    SadeepDarshana over 8 years
    do we get the exact color we choose here setColorFilter(0xff00ff00, PorterDuff.Mode.MULTIPLY ) if we use white as original color. If not how can we get the exact color?
  • MH.
    MH. over 8 years
    @SadeepDarshana: I'm not sure what you're asking here? MULITPLY is imply defined as [Sa * Da, Sc * Dc], meaning that the result is composed of multiplying the source's alpha channel with the destination's, and the same for each of the colour channels (r, g and b). If you make either source equal to 1 (ignoring alpha channel for simplicity), then the result is 1 * Dc = Dc, which is just the destination channel. Vice versa, if destination equals 1, then it's just the source channel. The same math applies to the alpha channel.
  • SadeepDarshana
    SadeepDarshana over 8 years
    got it thanks @MH. but is Sa in the range of [0,255] or [0,1]? i mean for this should i use (white) or RGB(1 out of 255, 1 out of 255, 1 out of 255) as the original color to work as I expected
  • MH.
    MH. over 8 years
    @SadeepDarshana: That would be [0,1], otherwise the multiplication operation (and many others) would make little sense. For more details on PorterDuff.Mode on Android, I'd suggest to have a read here or start a new question if you hit any snags.
  • SadeepDarshana
    SadeepDarshana over 8 years
    @MH. thanks, and I recommend MH.'s link for anyone interested
  • kelin
    kelin over 8 years
    I think author asked about any filter, not just SRC_ATOP or MULTIPLY.
  • Rahul Chowdhury
    Rahul Chowdhury over 7 years
    I had a PNG drawable for the ImageView and PorterDuff.Mode.SRC_IN worked correctly for me instead of PorterDuff.Mode.MULTIPLY
  • MH.
    MH. over 7 years
    @RahulChowdhury: Sure, depending on your use case you'll want to explore different modes. PorterDuff.Mode.MULTIPLY was just an example that fits the original question, and works because the initial colour of the circle is white. The point to take away here is how to apply a colour filter using one of the available PorterDuff.Mode options provided by the framework.
  • marlonpya
    marlonpya over 6 years
    nice answer not need run
  • Mahdi Khansari
    Mahdi Khansari almost 5 years
    Right solution for image views with PNG source