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

Viewed 1892

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?

3 Answers

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>

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.

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.

Related