views-widgets-samples icon indicating copy to clipboard operation
views-widgets-samples copied to clipboard

Cardview only top corner radius?

Open MujahidHi5 opened this issue 5 years ago • 7 comments

I need to add only top corner radius but i can see only app:cardCornerRadius="20" How can i do it?

MujahidHi5 avatar Aug 11 '20 05:08 MujahidHi5

You have to create a custom style for this. Within your styles.xml add the following:

    <style name="CustomCardCorners" parent="@style/Widget.MaterialComponents.CardView">
        <item name="shapeAppearanceOverlay">@style/ShapeAppearance_custom_corners</item>
    </style>

    <style name="ShapeAppearance_custom_corners" parent="">
        <item name="cornerFamily">rounded</item>
        <item name="cornerSizeTopLeft">4dp</item>
        <item name="cornerSizeTopRight">4dp</item>
    </style>

And then for your cardview, do:

<com.google.android.material.card.MaterialCardview
          style="@style/CustomCardCorners"
          // .. some other stuff  
/>

Berki2021 avatar Oct 13 '20 16:10 Berki2021

not working at all

richanshah avatar Mar 08 '21 07:03 richanshah

I have check above code but didnt work as apected, So i searched on StackOverflow and found ShapeAppearanceModel can be used to make corners for different sizes.

This is how I set topleft and topright corners in my screen,

<com.google.android.material.card.MaterialCardView
            android:id="@+id/cardview"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/guideline">

Below is Kotlin code:

   `  val leftShapePathModel = ShapeAppearanceModel().toBuilder()
        // You can change style and size
        leftShapePathModel.setTopLeftCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        leftShapePathModel.setTopRightCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        val bg = MaterialShapeDrawable(leftShapePathModel.build())
        // In my screen without applying color it shows black background
        bg.fillColor = ColorStateList.valueOf(
            requireContext().resources.getColor(android.R.color.white)
        )
        bg.elevation = 8F

        cardview.background = bg
        cardview.invalidate()`

Shvet avatar Apr 03 '21 08:04 Shvet

I have check above code but didnt work as apected, So i searched on StackOverflow and found ShapeAppearanceModel can be used to make corners for different sizes.

This is how I set topleft and topright corners in my screen,

<com.google.android.material.card.MaterialCardView
            android:id="@+id/cardview"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/guideline">

Below is Kotlin code:

   `  val leftShapePathModel = ShapeAppearanceModel().toBuilder()
        // You can change style and size
        leftShapePathModel.setTopLeftCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        leftShapePathModel.setTopRightCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        val bg = MaterialShapeDrawable(leftShapePathModel.build())
        // In my screen without applying color it shows black background
        bg.fillColor = ColorStateList.valueOf(
            requireContext().resources.getColor(android.R.color.white)
        )
        bg.elevation = 8F

        cardview.background = bg
        cardview.invalidate()`

With reference to this answer, using ShapeAppearanceModel.Builder , we can also set it directly using:

 val topcard=view.findViewById<MaterialCardView>(R.id.topcard)
 var shapeAppearanceModel: ShapeAppearanceModel.Builder =ShapeAppearanceModel().toBuilder()
 shapeAppearanceModel.setTopLeftCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })
topcard.shapeAppearanceModel =shapeAppearanceModel.build()

Thanks to @Shvet

ReejeshPK avatar May 29 '21 05:05 ReejeshPK

Does this work with 1.6.0 version? I tried with this following your examples, but so far is not working for me

<com.google.android.material.card.MaterialCardView
            android:id="@+id/card_view_video_player"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:cardElevation="0dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_description"
            android:layout_marginTop="@dimen/dp_80px"
            app:cardBackgroundColor="@android:color/transparent">

            <com.unknown.presentation.views.ui.videoplayer.MyCustomExoPlayer
                android:id="@+id/video_player"
                android:layout_width="@dimen/dp_605px"
                android:layout_height="@dimen/dp_1023px" />

        </com.google.android.material.card.MaterialCardView>
val topcard = binding.cardViewVideoPlayer
        val shapeAppearanceModel = ShapeAppearanceModel().toBuilder()
        shapeAppearanceModel.setTopLeftCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        shapeAppearanceModel.setTopRightCorner(
            CornerFamily.ROUNDED,
            CornerSize { return@CornerSize 80F })

        topcard.shapeAppearanceModel = shapeAppearanceModel.build()

dianamelga avatar Jan 11 '23 20:01 dianamelga

You can create a custom outline with extra height (i.e. viewHeight + radius) and make its alpha zero.

fun MaterialCardView.addTopCornerRadius(radius: Float) {
        val curveRadius = UIUtils.convertDpToPixel(binding.cvPoster.context, radius)
        outlineProvider = object : ViewOutlineProvider() {
            override fun getOutline(view: View?, outline: Outline?) {
                outline?.setRoundRect(0, 0, view!!.width, (view.height + curveRadius).toInt(), curveRadius)
                outline?.alpha = 0f
            }
        }
        clipToOutline = true
    }

hament9193 avatar Jul 09 '24 12:07 hament9193

I need to add only top corner radius but i can see only app:cardCornerRadius="20" How can i do ?

There is a shortcut- if you need it at the top of the page , you can margin CardView -20dp from the top . Then top top curve will not be visible ,but bottom bottom curve will be visible .

<androidx.cardview.widget.CardView

    app:cardElevation="@dimen/_5sdp"
    android:layout_marginTop="-50dp"
    app:cardCornerRadius="@dimen/_35sdp"
    android:background="@drawable/white_curve"
    android:padding="@dimen/_10sdp"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"> 

</androidx.cardview.widget.CardView>

Deluar-H-Nyeem avatar Aug 31 '24 22:08 Deluar-H-Nyeem