29
votes

I have the following CardView and I want to set different radius for each corner in the card. Is it possible to change them by XML or programmaticaly? Thanks in advance.

<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="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginRight="16dp"
    android:layout_marginLeft="16dp"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    app:cardCornerRadius="0dp"
    app:cardElevation="0dp">
</android.support.v7.widget.CardView>

EDIT As Avinash suggest, I am looking for the behaviour of this lib github.com/captain-miao/OptionRoundCardview but using the default CardView item. If it is not possible to change it individually, this lib is a good approach.

4
In case if we just need to shape an image, use the material ShapeableImageView that draws the bitmap with the provided Shape.Anoop M Maddasseri

4 Answers

79
votes

It requires the official MaterialCardView (which extends the androidx.cardview.widget.CardView) and at least the version 1.1.0 of the Material components library.

Add to your layout the MaterialCardView:

    <com.google.android.material.card.MaterialCardView
        style="@style/CustomCardViewStyle"
        ...>
      
    </com.google.android.material.card.MaterialCardView>

Define a custom style inheriting a material card style (for example Widget.MaterialComponents.CardView) and use the shapeAppearanceOverlay attribute:

  <style name="CustomCardViewStyle" parent="@style/Widget.MaterialComponents.CardView">
     <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay_card_custom_corners</item>
  </style>


  <style name="ShapeAppearanceOverlay_card_custom_corners" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">4dp</item>
    <item name="cornerSizeTopLeft">8dp</item>
    <item name="cornerSizeBottomRight">16dp</item>
    <item name="cornerSizeBottomLeft">0dp</item>
  </style>

enter image description here

You can also achieve it programmatically.
Just apply a custom ShapeAppearanceModel to the corners of the card.
Something like:

float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
  cardView.getShapeAppearanceModel()
      .toBuilder()
      .setTopLeftCorner(CornerFamily.ROUNDED,..)
      .setTopRightCorner(CornerFamily.ROUNDED,..)
      .setBottomRightCorner(CornerFamily.ROUNDED,radius)
      .setBottomLeftCornerSize(0)
      .build());

Note: it requires the version 1.1.0 of the library.


With Jetpack compose 1.0.0(tested with 1.0.0-rc02) you can use something like:

    Card(
        shape = RoundedCornerShape(
           4.dp,
           8.dp,
           16.dp,
           2.dp)
    ){
        Text("Content Card")
    }

enter image description here

2
votes

You can create a custom xml and name it rounded_corners.xml like this:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="1dp"
    android:topLeftRadius="20dp"
    android:topRightRadius="30dp"
    android:bottomLeftRadius="40dp"
    android:bottomRightRadius="50dp"/>
<solid android:color="your_background_color" />
</shape>

And then use this as the background for your CardView:

android:background="@drawable/rounded_corners"

EDIT: I just noticed that this may work for all other views other than CardView, so refer to this question for seeing how to do a workaround.

0
votes

NOTE: This here is a workaround if you want to achieve rounded corners at the bottom only and regular corners at the top. This will not work if you want to have different radius for all four corners of the cardview. You will have to use material cardview for it or use some third party library.

Here's what seemed to work for me:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="#F9F9F9">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@drawable/profile_bg"/>

    </androidx.cardview.widget.CardView>

    <androidx.cardview.widget.CardView
        android:id="@+id/cvProfileHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardCornerRadius="32dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="280dp"
            android:orientation="vertical"
            android:background="@drawable/profile_bg"
            android:id="@+id/llProfileHeader"
            android:gravity="center_horizontal">

            <!--Enter your code here-->

        </LinearLayout>
    
    </androidx.cardview.widget.CardView>

</RelativeLayout>

There's two cardview's in all. The second cardview is the one that will have rounded corners (on all sides as usual) and will hold all other subviews under it. The first cardview above it is also at the same level (of elevation), and has the same background but is only about half the height of the second cardview and has no rounded corners (just the usual sharp corners). This way I was able to achieve partially rounded corners on the bottom and normal corners on the top. But for all four sides, you may have to use the material cardview.

-1
votes

Hi you can add it programmatically or by xml with following code.

app:cardCornerRadius="0dp"// xml
cardView.setRadius(0);

this one is extra who is looking for elevation

app:cardElevation="0.7dp"//xml
app:cardMaxElevation="1dp"//xml
cardView.setCardElevation(2.1f);//code
cardView.setMaxCardElevation(3f);//code

The complete Java representation of the CardView’s XML.

CardView cardView = (CardView) findViewById(R.id.cardView);
cardView.setUseCompatPadding(true);
cardView.setContentPadding(30, 30, 30, 0);
cardView.setPreventCornerOverlap(true);
cardView.setCardBackgroundColor(Color.WHITE);
cardView.setCardElevation(2.1f);
cardView.setRadius(0);
cardView.setMaxCardElevation(3f);