How do I create a CardView with a semitransparent background color and a corner radius?

Viewed 909

I'm trying to make a CardView with a background of #88FFFFFF, and with rounded corners. It doesn't work properly, with the corners being doubly opaque in Android Studio, and the whole border being doubly opaque on my device.

Here is the code:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="100dp"
    android:layout_height="100dp"
    app:cardBackgroundColor="#88FFFFFF"
    app:cardElevation="2dp"
    app:cardCornerRadius="12dp">

</android.support.v7.widget.CardView>

And here is the result:

sad

Is there a way to fix this without creating a drawable for the background?

4 Answers

Just use linear layout inside Cardview. set linearlayout background with "#88FFFFFF".

<CardView>
    <LinearLayout background=""></LinearLayout>
</CardView>

Try this

<android.support.v7.widget.CardView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:cardBackgroundColor="#88FFFFFF"
        app:cardCornerRadius="6dp"
        app:cardUseCompatPadding="true"
        app:cardElevation="5dp">

Try to remove elevation, which is available in new MaterialCardView component

app:cardElevation="0dp"
app:cardMaxElevation="0dp"

You can also add stroke, e.g.

app:strokeColor="#f9d5e9"
app:strokeWidth="1.5dp"

I had this issue with CardView in Xamarin.Android and came to this solution:

This is in C#/Xamarin but the Java/Kotlin code would be quite similar.

      // There is a bug with CardView
      // Where setting a semi-transparent colour + corner radius + elevation will display a border with the opaque (a=255) colour.
      // To resolve this I'm manually calculating the desired colour (with a=255/2) and using an 
      // Android.Graphics.Color without using the alpha channel
 
      float opacity = 0.5f;
      var color = GetDesiredColorOpaque();
      var viewBgColor = GetViewBgColor(); 
      var desiredColor = new Color(color.R, color.G, color.B, color.A / 2); // not used - but resulting flattenedCardColor will look equivalent without transparency
 
      // Formula based on https://filosophy.org/code/online-tool-to-lighten-color-without-alpha-channel/
      // NB this only works because we're not really needing transparency i.e. the resulting card is not transparent, it is just colored as if it was transparent and behind it was just empty viewBgColor 
      var flattenedCardColor = new Color(
        r: (byte) (opacity * color.R + (1 - opacity) * viewBgColor.R),
        g: (byte) (opacity * color.G + (1 - opacity) * viewBgColor.G),
        b: (byte) (opacity * color.B + (1 - opacity) * viewBgColor.B),
        a: (byte) 255);
      
      cardView.CardBackgroundColor = Android.Content.Res.ColorStateList.ValueOf(flattenedCardColor);

Do note that this solution works by calculating the desired CardView background color using an opacity equation, so it will not actually make the CardView transparent. I did this because I assumed this problem is caused by some bug with CardView and semi-transparent colors, as no proposed solutions were working for my use case (requirement of programmatically styling the CardView colors).

The result you get is correctly colored CardView background as if the opacity was being set in the alpha channel, and there are no visual bugs when using cardElevation and/or cardCornerRadius.

Thanks to https://filosophy.org/code/online-tool-to-lighten-color-without-alpha-channel/ for the equation.

Related