I want to corner only the top of a cardview.
I used below property and it is rounding all the corner.
I want to show an overlap of all cards
card_view:cardCornerRadius="4dp"
here is my layout
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
card_view:cardCornerRadius="4dp"
card_view:cardPreventCornerOverlap="false"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="@+id/re1">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/colorAccent"
android:text="contact det"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:textSize="14dp"/>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="@id/title"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"/>
<TextView
android:id="@+id/txtSurname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Surname"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="@id/txtName"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
/>
<TextView
android:id="@+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:layout_marginRight="150dp"
android:layout_alignBaseline="@id/txtName"/>
<TextView
android:id="@+id/txtAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textSize="10dp"
android:layout_alignLeft="@id/txtEmail"
android:layout_alignBaseline="@id/txtSurname"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
We can set the marginBottom of the card view in negative value.Margin should be same value as card radius.
For Example,
<FrameLayout
android:id="@+id/rootview"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_marginBottom="-3dp"
project:cardCornerRadius="3dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--The child view inside the cardview should have extra padding,so that negative margin will not affect the bottom padding of its child.Here normally we have 16dp bottom padding for child + margin bottom of the parent is 3dp=19dp comes.-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="19dp"/>
</android.support.v7.widget.CardView>
</FrameLayout>
It works for me.But I am in doubt whether it is the proper way of doing.Any suggestions are welcome.
I have been trying the same but none of the solutions provided worked for me.
The only thing that worked was:
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);
Worked perfectly for me! Hope this helps you.
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.
Tricky thing because you can't make CardView do this. Internally it uses a RoundRectDrawable
(package private) which uses roundRect
like this:
// rectf, rx, ry, paint
canvas.drawRoundRect(mBoundsF, mRadius, mRadius, paint);
Therefore you need a different solution, for example I found this gist by Ahmed-Abdelmeged where they use canvas clipping per each corner using a path to describe the outline.
So while I'm not the one who made this code, I'll post it here for future travellers.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RoundedView">
<attr name="topLeftCornerRadius" format="dimension" />
<attr name="topRightCornerRadius" format="dimension" />
<attr name="bottomLeftCornerRadius" format="dimension" />
<attr name="bottomRightCornerRadius" format="dimension" />
</declare-styleable>
</resources>
and
package com.abdelmeged.ahmed.roundedlayout;
/**
* Created by ahmed on 9/17/2017.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Region;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
/**
* Custom wrapper view to get round corner round view
*/
public class RoundedView extends FrameLayout {
/**
* The corners than can be changed
*/
private float topLeftCornerRadius;
private float topRightCornerRadius;
private float bottomLeftCornerRadius;
private float bottomRightCornerRadius;
public RoundedView(@NonNull Context context) {
super(context);
init(context, null, 0);
}
public RoundedView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public RoundedView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context, AttributeSet attrs, int defStyle) {
TypedArray typedArray = context.obtainStyledAttributes(attrs,
R.styleable.RoundedView, 0, 0);
//get the default value form the attrs
topLeftCornerRadius = typedArray.getDimension(R.styleable.
RoundedView_topLeftCornerRadius, 0);
topRightCornerRadius = typedArray.getDimension(R.styleable.
RoundedView_topRightCornerRadius, 0);
bottomLeftCornerRadius = typedArray.getDimension(R.styleable.
RoundedView_bottomLeftCornerRadius, 0);
bottomRightCornerRadius = typedArray.getDimension(R.styleable.
RoundedView_bottomRightCornerRadius, 0);
typedArray.recycle();
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void dispatchDraw(Canvas canvas) {
int count = canvas.save();
final Path path = new Path();
float[] cornerDimensions = {
topLeftCornerRadius, topLeftCornerRadius,
topRightCornerRadius, topRightCornerRadius,
bottomRightCornerRadius, bottomRightCornerRadius,
bottomLeftCornerRadius, bottomLeftCornerRadius};
path.addRoundRect(new RectF(0, 0, canvas.getWidth(), canvas.getHeight())
, cornerDimensions, Path.Direction.CW);
canvas.clipPath(path);
super.dispatchDraw(canvas);
canvas.restoreToCount(count);
}
public void setTopLeftCornerRadius(float topLeftCornerRadius) {
this.topLeftCornerRadius = topLeftCornerRadius;
invalidate();
}
public void setTopRightCornerRadius(float topRightCornerRadius) {
this.topRightCornerRadius = topRightCornerRadius;
invalidate();
}
public void setBottomLeftCornerRadius(float bottomLeftCornerRadius) {
this.bottomLeftCornerRadius = bottomLeftCornerRadius;
invalidate();
}
public void setBottomRightCornerRadius(float bottomRightCornerRadius) {
this.bottomRightCornerRadius = bottomRightCornerRadius;
invalidate();
}
}
This will let you clip the edge of images and views before they get rendered, therefore it does exactly what you want.
As per the question, I am assuming that you want to apply corner radius property to only top of the card. You can obtain this effect by using two CardView
. Place one CardView
inside another CardView
and remove outer CardView
corner radius property. Also apply a transparent background to your outer CardView
Your inner CardView will have a cornerRadius value of 4dp. Then apply a marginTop to your inner CardView
, so that its bottom part becomes hidden by the outer CardView
. This way, the bottom corner radius of your inner CardView
will be hidden.
You will have to put your xml content in your Inner CardView
. Outer CardView
serves only the purpose of hiding the bottom rounded corners of the inner CardView
.
Your xml layout will look like this:
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:layout_gravity="center"
card_view:cardBackgroundColor="@android:color/transparent"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="4dp" >
<android.support.v7.widget.CardView
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="3dp"
card_view:cardElevation="0dp"
card_view:cardCornerRadius="4dp"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:id="@+id/re1">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@color/colorAccent"
android:text="contact det"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:textSize="14dp"/>
<TextView
android:id="@+id/txtName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="@id/title"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"/>
<TextView
android:id="@+id/txtSurname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Surname"
android:gravity="center_vertical"
android:textSize="10dp"
android:layout_below="@id/txtName"
android:layout_marginTop="10dp"
android:layout_marginLeft="5dp"
/>
<TextView
android:id="@+id/txtEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="10dp"
android:layout_marginTop="10dp"
android:layout_alignParentRight="true"
android:layout_marginRight="150dp"
android:layout_alignBaseline="@id/txtName"/>
<TextView
android:id="@+id/txtAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Address"
android:textSize="10dp"
android:layout_alignLeft="@id/txtEmail"
android:layout_alignBaseline="@id/txtSurname"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
</android.support.v7.widget.CardView>
I have taken reference from this SO question: Question.
I hope it solves your problem.