Is there a way to make CardView only have corner radius at the top?
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="10dp"
>
This question is related to
android
android-appcompat
android-cardview
Unless you try to extend the Android CardView
class, you cannot customize that attribute from XML
.
Nonetheless, there is a way of obtaining that effect.
Place a CardView
inside another CardView
and apply a transparent background to your outer CardView
and remove its corner radius ("cornerRadios = 0dp"
). Your inner CardView
will have a cornerRadius value of 3dp, for example. Then apply a marginTop to your inner CardView
, so its bottom bounds will be cut by the outer CardView
. This way, the bottom corner radius of your inner CardView
will be hidden.
The XML code is the following:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view_outer"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
card_view:cardBackgroundColor="@android:color/transparent"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="3dp" >
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view_inner"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="3dp"
card_view:cardBackgroundColor="@color/green"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="0dp" >
</android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
And the visual effect is the following:
Always put your content in your Inner CardView
. Your outer CardView serves only the purpose of "hiding" the bottom Rounded Corners of the inner CardView
.
You can use the standard MaterialCard
included in the official Material Components library.
Use in your layout:
<com.google.android.material.card.MaterialCardView
style="@style/MyCardView"
...>
In your style use the shapeAppearanceOverlay
attribute to customize the shape (the default corner radius is 4dp
)
<style name="MyCardView" parent="@style/Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.MaterialCardView.Cut</item>
</style>
<style name="ShapeAppearanceOverlay.MaterialCardView.Cut" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopRight">8dp</item>
<item name="cornerSizeTopLeft">8dp</item>
<item name="cornerSizeBottomRight">0dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
You can also use:
<com.google.android.material.card.MaterialCardView
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Cut"
...>
It is the result:
dependencies: compile 'com.android.support:cardview-v7:23.1.1'
<android.support.v7.widget.CardView
android:layout_width="80dp"
android:layout_height="80dp"
android:elevation="12dp"
android:id="@+id/view2"
app:cardCornerRadius="40dp"
android:layout_centerHorizontal="true"
android:innerRadius="0dp"
android:shape="ring"
android:thicknessRatio="1.9">
<ImageView
android:layout_height="80dp"
android:layout_width="match_parent"
android:id="@+id/imageView1"
android:src="@drawable/Your_image"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true">
</ImageView>
</android.support.v7.widget.CardView>
An easy way to achieve this would be:
1.Make a custom background resource (like a rectangle shape) with rounded corners.
2.set this custom background using the command -
cardView = view.findViewById(R.id.card_view2);
cardView.setBackgroundResource(R.drawable.card_view_bg);
this worked for me.
The XML
layout I made with top left and bottom right radius.
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners android:topLeftRadius="18dp" android:bottomRightRadius="18dp" />
</shape>
In your case, you need to change only topLeftRadius as well as topRightRadius.
If you have a layout that overlaps with the corners of the card view and has a different color maybe, then you might need a different background resource file for the layout and in the xml set this background resource to your layout.
I tried and tested the above method. Hope this helps you.
If you're setting the card background programmatically, make use you use cardView.setCardBackgroundColor()
and not cardView.setBackgroundColor()
and make sure use using app:cardPreventCornerOverlap="true"
on the cardView.xml. That fixed it for me.
Btw, the above code (in quotations) is in Kotlin and not Java. Use the java equivalent if you're using Java.
Easiest way to achieve it in Android Studio is explained below:
Step 1:
Write below line in dependencies in build.gradle
:
compile 'com.android.support:cardview-v7:+'
Step 2:
Copy below code in your xml file for integrating the CardView
.
For cardCornerRadius
to work, please be sure to include below line in parent layout:
xmlns:card_view="http://schemas.android.com/apk/res-auto"
And remember to use card_view
as namespace for using cardCornerRadius
property.
For example : card_view:cardCornerRadius="4dp"
XML Code:
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view_outer"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
card_view:cardBackgroundColor="@android:color/transparent"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="3dp" >
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/card_view_inner"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="3dp"
card_view:cardBackgroundColor="@color/green"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="0dp" >
</android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
You can put your ImageView inside a CardView, and add those properties to the ImageView:
android:cropToPadding="true"
android:paddingBottom="15dp"
That way you will get rid of the rounded bottom corner, but keep in mind that this comes in the price of having a small portion of your image cut off.
You need to do 2 things :
1) Call setPreventCornerOverlap(false)
on your CardView.
2) Put rounded Imageview inside CardView
About rounding your imageview, I had the same problem so I made a library that you can set different radii on each corner. Finally I got the result what I wanted like below.
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.
You could do the reverse of this to get rounded corners at the top and regular ones at the bottom, i.e. let the first cardview have rounded corners and the second cardview have regular corners.
I wrote a drawable lib to custom round corner position, it looks like this:
You can get this lib at here:
There is an example how to achieve it, when the card is at the very bottom of the screen. If someone has this kind of problem just do something like that:
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-5dp"
card_view:cardCornerRadius="4dp">
<SomeView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp">
</SomeView>
</android.support.v7.widget.CardView>
Card View has a negative bottom margin. The view inside a Card View has the same, but positive bottom margin. This way rounded parts are hidden below the screen, but everything looks exactly the same, because the inner view has a counter margin.
You can use this drawable xml and set as background to cardview :
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffffff"/>
<stroke android:width="1dp"
android:color="#ff000000"
/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
/>
<corners
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
you can use the library:OptionRoundCardview
Source: Stackoverflow.com