Home > database >  setTextColor and setColorFilter not the same color in Kotlin
setTextColor and setColorFilter not the same color in Kotlin

Time:10-04

I have an ImageView and a TextView. They both use ?attr/somecolor to see what color they have to use depending on what theme is selected. This somecolor is either black or white depending on theme.

Now when I say they both need to be red using R.color.red, the TextView has a more brighter red then the ImageView.

sometext.setTextColor(ContextCompat.getColor(this,R.color.green))
someimage.setColorFilter(ContextCompat.getColor(this, R.color.green))

Is there any reason why these colors don't match up?

enter image description here

CodePudding user response:

Instead of using the ?astr which is for the main portion of the app user interface example navbar and things like that. You can create your color as Third Primary Color and just call it from there. I only use the ?astr for main color of the title bar or nav bar.

When you define the color as a third primary define the same color in both themes. You should get the same color for both. I do this a lot on all of my apps.

Also Android Studio is yelling at me saying that the ?astr is no longer needed. So I have a feeling that it will be done away with in the future.

Also defining your own colors will ensure the colors are the same. Be sure to set the same #13345fg(not actual color) with both themes that are pre-built for the app.

CodePudding user response:

For what it's worth, here's what I get for an ImageView with app:tint="@color/black and a TextView with android:textColor="@colorBlack, and then

someText.setTextColor(Color.RED)
someImage.setColorFilter(Color.RED)

The result with both elements tinted the same colour

It's hard to say exactly what you need to do, but there are two different things going on here. For the TextView, you're literally just telling it what colour to draw with. That should always come out looking how you expect.

But for images, it's a little more complicated. You're applying a tint over existing image data, which interacts with the original colours and alpha to produce a final mixed image. For a bitmap image, that colour is in the individual pixels. For a vector drawable, it's in attributes like the fillColor.

For example, that fill colour on the arrow is @color/white, but here's what happens if I knock the alpha down by setting android:fillColor="#AAFFFFFF":

The full red applied over a vector drawable with less than full alpha

You can see the colour is different - it's actually partially transparent so it's blending with the white background. Applying full-alpha red over it didn't change the overall alpha - and it can't really, it's the alpha that says which parts of that square image are "empty" and which are "the arrow". (Well, you can do that with a different PorterDuff mode, but by default it doesn't!)


The alpha of your tint matters too - here's a partially transparent tint applied to the @color/white arrow (and the text):

someText.setTextColor(Color.parseColor("#99FF0000"))
someImage.setColorFilter(Color.parseColor("#99FF0000"))

Tint applied to white arrow - it's pale red

And here's the same tint applied when the arrow's fill colour is @color/black

Tint applied to black arrow - it's noticeably darker

So the colour tint, when it's partially transparent, only really shifts the overall colour appearance, rather than fully replacing it. So check your R.color.green value and make sure it's actually fully opaque. If it's not, and that's how you want it, then pay attention to the fillColor you're using - you can see there that I'm applying the exact same colour to the text, but it matches more closely when the arrow is white


The other thing is the different PorterDuff tinting modes you can apply with setColorFilter - I can't really go into them right now (some info here and here) but you can control how the tint colour and the image are composited, how they're blended together.

Ideally you'd just make your image's fillColor white and apply your tint to it and call it a day, but if you can't do that (because it's in use elsewhere) or you need to tint bitmaps, you can look into that stuff!

  • Related