How do I add an alpha channel to an existing Android color in xml

3.2k views Asked by At

I have the following color in values/colors.xml:

<color name="grey_1">#0F0E10</color>

I want to reference this color in a gradient:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="-90"
        android:startColor="#000F0E10"
        android:endColor="#990F0E10"/>
</shape>

However, this duplicates the RGB color definition. Ideally, I'd like to write something like this:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="-90"
        android:startColor="alpha(00, @color/grey_1)"
        android:endColor="alpha(99, @color/grey_1)"/>
</shape>

or this:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="-90"
        android:startColor="@color/grey_1"
        android:startTransparency="#00"
        android:endColor="@color/grey_1"
        android:endTransparency="#99"/>
</shape>

Is this possible?

5

There are 5 answers

0
Jeffrey Blattman On BEST ANSWER

You have to do it in code. You can get a color like this,

int color = getResources().getColor(R.color.<the color>);

You can turn it into ARGB like this:

int a = Color.alpha(color);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);

Now you can re-create the color with whatever alpha you want:

color = Color.argb(<new alpha>, r, g, b);

This means of course you'd need to construct your drawable from code. Not as clean but possible.

0
jack_the_beast On

I would also like to point out that it can be done programmatically with ColorStateList.withAlpha()

like so:

csl.withAlpha(0) //transparent
csl.withAlpha(255) //opaque
0
Alexandre Martin On

You must set two distinct colors as the starting and the ending colors.

Remember that colors are defined this way : #AARRGGBB for Alpha, Red, Green and Blue.

Once the app is launched, ressources are in read only mode. You can't change them programmatically on a proper way.

0
Heath Borders On

You can do this in API 23 and higher with a ColorStateList.

From the docs:

Starting with API 23, items may optionally define an android:alpha attribute to modify the base color's opacity. This attribute takes a either floating-point value between 0 and 1 or a theme attribute that resolves as such. The item's overall color is calculated by multiplying by the base color's alpha channel by the alpha value. For example, the following item represents the theme's accent color at 50% opacity:

<item android:state_enabled="false"
      android:color="?android:attr/colorAccent"
      android:alpha="0.5" />

Thus, in my case, I would do:

color/gradient_start_color.xml:

<item android:color="@color/grey_1"
      android:alpha="0" />

color/gradient_end_color.xml:

<item android:color="@color/grey_1"
      android:alpha="0.6" />

drawable/gradient.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:type="linear"
        android:angle="-90"
        android:startColor="@color/gradient_start_color"
        android:endColor="@color/gradient_end_color" />
</shape>
0
salih On

Try to use ColorUtils class from androidx.core.graphics package, for example;

 int color = getResources().getColor(R.color.border_active_default);
 circle.setFillColor(ColorUtils.setAlphaComponent(color,50));

Then you don't have to implement your own custom approach.