Android Dev Tip #3
Using @android:color/transparent in gradients
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:
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:
R, G and B components are not changing. Only the Alpha channel is affected by the gradient.