Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to change the radius of specific corner of Material design CardView

I am using material design in my android app and normally for changing the radius of the corner of card i use app:cardCornerRadius, but this will change all the four corner of card. I want to change any specific corner of the card. I dont want to use drawable only for changing the corner. Is there any way through xml or programatically.

 <com.google.android.material.card.MaterialCardView
        style="@style/Widget.MaterialComponents.CardView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:backgroundTint="@color/colorWhite"
        app:cardCornerRadius="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginStart="16dp" android:layout_marginEnd="16dp">
    <androidx.constraintlayout.widget.ConstraintLayout
            android:visibility="visible"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
like image 852
Amit Sen Avatar asked Jun 01 '19 16:06

Amit Sen


2 Answers

With the version 1.1.0 of the Material Component you can customize the shape of your component using the shapeAppearanceOverlay attribute.
You can use it in the view or in the style.

<com.google.android.material.card.MaterialCardView
      .....
      app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut">

and then define your favorite shape:

  <style name="ShapeAppearanceOverlay.MaterialCardView.Cut" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">0dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomRight">16dp</item>
    <item name="cornerSizeBottomLeft">16dp</item>
  </style>

enter image description here

With the code you can apply a custom ShapeAppearanceModel to the corner of the card using something like:

float radius = getResources().getDimension(R.dimen.my_corner_radius);
cardView.setShapeAppearanceModel(
  cardView.getShapeAppearanceModel()
      .toBuilder()
      .setAllCorners(CornerFamily.ROUNDED,radius)
      .setTopRightCornerSize(0)
      .build());
like image 71
Gabriele Mariotti Avatar answered Sep 28 '22 08:09

Gabriele Mariotti


I have a solution but it requires v21 Lollipop and above. You can do it programmatically as follows:

In your activity class have public static int radius = 20; and in your Oncreate();

CardView card = findViewById(R.id.my_card);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   makeCustomOutline(card);
}

then define the function as follows:

 @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void makeCustomOutline(CardView card){

    card.setOutlineProvider(new ViewOutlineProvider() {
        @Override
        public void getOutline(View view, Outline outline) {

            outline.setRoundRect(0, 0, view.getWidth(),
                    (view.getHeight() + radius), (float)radius );
        }
    });
    card.setClipToOutline(true);

}

by using the setRoundRect() method you can control which corner of the cardview gets the radius and which doesn't. The above code will make only the top corners rounded, bottom corners will not be rounded.

References:

This answer was adapted from this article

docs on setRoundRect() method

docs on ViewOutlineProvider

like image 24
Edgar Avatar answered Sep 28 '22 06:09

Edgar