android / views-widgets-samples

Multiple samples showing the best practices in views-widgets on Android.
Apache License 2.0
5.08k stars 3.01k forks source link

Cardview only top corner radius? #169

Open MujahidHi5 opened 4 years ago

MujahidHi5 commented 4 years ago

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

Berki2021 commented 4 years ago

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  
/>
richanshah commented 3 years ago

not working at all

Shvet commented 3 years ago

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()`
ReejeshPK commented 3 years ago

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

dianamelga commented 1 year ago

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()
hament9193 commented 4 months ago

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
    }
Deluar-H-Nyeem commented 3 months ago

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>