Ayyappan
Ayyappan

Reputation: 1265

Unable to get exact circle shape when using card view

I'm using card view for floating action button in android material design. I'm using following code for get the circle

<android.support.v7.widget.CardView
    android:id="@+id/fab"
    android:layout_width="38dp"
    android:layout_height="38dp"
    android:layout_marginBottom="10dp"
    android:layout_marginRight="10dp"
    card_view:background="@color/blue"
    card_view:cardCornerRadius="19dp"
    card_view:cardPreventCornerOverlap = "false"
    card_view:cardElevation="6dp" >
</android.support.v7.widget.CardView>

I have set corner radius as half of width. but still I can't get the circle shape.enter image description here

Upvotes: 46

Views: 59786

Answers (12)

Dhruv Kaushal
Dhruv Kaushal

Reputation: 680

I came up with simple Solution of Using a Drawable and it looks amazing!

Get Drawable here https://drive.google.com/drive/folders/0B4Vo_ku-aIKzUFFnUjYxYVRLaGc?resourcekey=0-RiH8lUO0i1kwnZsqquqjnQ&usp=sharing

enter image description here

Upvotes: 8

Mohamed AbdelraZek
Mohamed AbdelraZek

Reputation: 2819

add this line to the CardView which sets the cardCornerRadius to the Circle diameter.

app:cardCornerRadius="360dp"

Upvotes: 5

rizwan
rizwan

Reputation: 164

Using CardView to obtain circular background with shadow can be quiet troublesome intead use layer-list in drawable to get the desired output.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <shape android:shape="oval">
            <!--shadow color you want-->
            <solid android:color="#C3C1C1"/>
        </shape>
    </item>

    <item
        android:left="0dp"
        android:right="0dp"
        android:top="0dp"
        android:bottom="2dp">
        <shape android:shape="oval">
            <solid android:color="@color/white"/>
        </shape>
    </item>
</layer-list>

Upvotes: -1

balu koppineedi
balu koppineedi

Reputation: 81

<androidx.cardview.widget.CardView
        android:layout_width="60dp"
        android:layout_marginStart="150dp"
        app:cardCornerRadius="360dp"
        android:layout_height="60dp">

Upvotes: 8

behrad
behrad

Reputation: 1278

first import the drawbleToolBox library in your project. with this library, you can create drawable dynamically.

for make your cardview circle your radius must be half of its height/widht.

                int radius = cardView.getHeight()/2;
                Drawable drawable = new DrawableBuilder()
                    .rectangle()
                    .solidColor(0xffffffff)

                    .topRightRadius(radius) // in pixels
                    .bottomRightRadius(radius)
                     //otherplaces
                    .build();



                holder.cardView.setBackground(drawable);

if you are using cardview in your recycleview, getting the cardview widths doesn't work becuse it doesn't create yet. so you should do as below

holder.cardView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
    {
        @Override
        public boolean onPreDraw()
        {
         //codes here.
        }
     }

Upvotes: 0

Kumar Ajay
Kumar Ajay

Reputation: 262

card_layout.xml

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="250dp"
    android:layout_height="200dp">

    <ImageView
        android:id="@+id/card_thumbnail_image"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        style="@style/card_thumbnail_image"/>
</android.support.v7.widget.CardView>

MainActivity.java

 ImageView imageView = (ImageView) findViewById(R.id.card_thumbnail_image);
    Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rose);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        //Default 
        imageView.setBackgroundResource(R.drawable.rose);
    } else {
        //RoundCorners 
        RoundCornersDrawable round = new RoundCornersDrawable(mBitmap,
                getResources().getDimension(R.dimen.cardview_default_radius), 0); //or your custom radius

        CardView cardView = (CardView) findViewById(R.id.card_view);
        cardView.setPreventCornerOverlap(false); //it is very important

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            imageView.setBackground(round);
        else
            imageView.setBackgroundDrawable(round);
    }

RoundCornersDrawable.java

    public class RoundCornersDrawable extends Drawable {

    private final float mCornerRadius;
    private final RectF mRect = new RectF();
    //private final RectF mRectBottomR = new RectF();
    //private final RectF mRectBottomL = new RectF();
    private final BitmapShader mBitmapShader;
    private final Paint mPaint;
    private final int mMargin;

    public RoundCornersDrawable(Bitmap bitmap, float cornerRadius, int margin) {
        mCornerRadius = cornerRadius;

        mBitmapShader = new BitmapShader(bitmap,
                Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(mBitmapShader);

        mMargin = margin;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        super.onBoundsChange(bounds);
        mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin);
        //mRectBottomR.set( (bounds.width() -mMargin) / 2, (bounds.height() -mMargin)/ 2,bounds.width() - mMargin, bounds.height() - mMargin);
       // mRectBottomL.set( 0,  (bounds.height() -mMargin) / 2, (bounds.width() -mMargin)/ 2, bounds.height() - mMargin);
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint);
        //canvas.drawRect(mRectBottomR, mPaint); //only bottom-right corner not rounded
        //canvas.drawRect(mRectBottomL, mPaint); //only bottom-left corner not rounded

    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }


}

Upvotes: 0

Rahul Kushwaha
Rahul Kushwaha

Reputation: 6752

Yes, I have achieved it by reducing half of the CardCornerRadius to its View's Height.

Upvotes: 1

Gautam Kumar
Gautam Kumar

Reputation: 1463

use

shape = "ring"

use same layout_height and layout_weight

and

app:cardCornerRadius= half of layout_height or layout_weight

example

<android.support.v7.widget.CardView
                        android:id="@+id/cardview"
                        android:layout_width="110dp"
                        android:layout_height="110dp"
                        android:shape="ring"
                        app:cardCornerRadius="55dp">
</android.support.v7.widget.CardView>

Upvotes: 12

silent_control
silent_control

Reputation: 612

To achieve a circular shape using Card view you can set the shape property, android:shape="ring".
app:cardCornerRadius should be set to half the width or height of the child view

<android.support.v7.widget.CardView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:innerRadius="0dp"
        android:shape="ring"
        app:cardCornerRadius="75dp">

        <ImageView
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:layout_gravity="center"
            android:background="@drawable/image" />
     </android.support.v7.widget.CardView>

Upvotes: 42

Alexandr Kotikov
Alexandr Kotikov

Reputation: 426

To get a perfect circle shape using a card view, corner radius should be 1/2 of width or height (taking into consideration that it is a square). also, I have noticed that you are using card_view params, don't.

<android.support.v7.widget.CardView
android:layout_width="38dp"
android:layout_height="38dp"
app:cardCornerRadius="19dp"
app:cardElevation="6dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:id="@+id/fab"
android:background="@color/blue"
>

Upvotes: 25

Ayyappan
Ayyappan

Reputation: 1265

I have solved the problem. Now android providing design library for material design, which has the FloatingActionButton. No need of customizing card view for floating action button.

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"  />

Add design library in gradle dependencies

compile 'com.android.support:design:23.1.1'

For more detail refer this link

Upvotes: 26

Collins Abitekaniza
Collins Abitekaniza

Reputation: 4588

I tried your code and found out that the Cards were less round with respect to the increase in the card elevation value.Try setting it to zero and this at least makes it look better.

card_view:cardElevation="0dp";

But a probably better option would be to use the FloatingActionButton for the round button

<android.support.design.widget.FloatingActionButton
    android:src="@drawable/your_drawble_name"
    app:fabSize="normal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Upvotes: 6

Related Questions