Android Dev Tip #3

Using @android:color/transparent in gradients

Bartek Lipinski
AndroidPub

--

This one is extremely basic and perfectly logical if you spend at most few seconds thinking about it. Nevertheless I have seen so many people struggling with it and I’ve been asked so many times about it, I decided to include it in the Dev Tip series.

Tip:

If you’re creating a gradient in xml with a part being completely transparent, be really careful when using @android:color/transparent.

Explanation:

When drawing a gradient, Android framework takes two colors representing two edges of the gradient section (startColor - centerColor or centerColor - endColor or startColor- endColor when no centerColor is specified) and interpolates values between them.

That means that the framework takes all four components of the color value (Alpha, Red, Green and Blue) and interpolates each and every single one of them for the particular part of gradient.

Here’s an example of creating a gradient between two colors:

if there were only 3 steps (colors) between them.

The values of the particular color components (A, R, G and B) at a particular stage of the gradient can be represented as:

When using @android:color/transparent you need to remember that it represents a completely transparent version of a particular color (opacity set to 0%; A component is equal to #00). You cannot forget this color has its own RGB components which are NOT skipped when calculating gradient values.

If you look at the Color class (from the android.graphics) you can see that Color.TRANSPARENT (which represents the same thing as @android:color/transparent) is equal to 0.

The hex representation of 0 is #00000000, which means that Color.TRANSPARENT is essentially a completely transparent Color.BLACK.

Example:

When creating a simple green-to-transparent gradient you might end up trying to use something like this:

With the visual result being:

Looks kind of ugly, doesn’t it? The gradient transforms #FF27AE60 green (#FF Alpha channel means 100% opacity) to completely transparent black (#00000000). Take a look at how particular components of the color are changing:

(the box in the bottom-right corner is completely transparent, because it’s black with 0% opacity)

If you think about that for a second, you should realize that creating a simple COLOR-TO-TRANSPARENT gradient shouldn’t modify RGB values at all. It should only affect the Alpha component. Which obviously isn’t the case here.

When using @android:color/transparent we cannot forget that Red, Green and Blue of this color are also taken into consideration when calculating color values for gradient. Not only the Alpha channel.

The proper way to generate this sort of gradient would be to use this:

Use the exact same color but change the opacity (Alpha) value to #00. The effect you would achieve is this (as expected):

And components would change in the following way:

(once again the difference between 25% opacity and 0% seems to be bigger than others, but that’s entirely correct… remember it’s essentially a jump from a color to nothing, while others are from a color to a more transparent color)

R, G and B components are not changing. Only the Alpha channel is affected by the gradient.

If you enjoyed this post, please show your support! Recommend, follow, comment, share.

This really means a lot!

--

--

Bartek Lipinski
AndroidPub

android engineer @whatnot | ex @reddit | ex @getthefabulous | recovering feature creep 💉 | https://github.com/blipinsk