使用卡片视图时无法获得精确的圆形

时间:2015-03-16 10:37:47

标签: android material-design android-cardview

我在android材料设计中使用卡片视图进行浮动操作按钮。我正在使用以下代码获取圈子

<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>

我将拐角半径设置为宽度的一半。但我仍然无法获得圆形。enter image description here

12 个答案:

答案 0 :(得分:19)

我已经解决了这个问题。现在android为材料设计提供了设计库,其中FloatingActionButton.不需要为浮动动作按钮定制卡片视图。

<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"  />

在gradle依赖项中添加设计库

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

有关详细信息,请参阅此link

答案 1 :(得分:12)

要使用卡片视图获得完美的圆形,角半径应为宽度或高度的1/2(考虑到它是正方形)。另外,我注意到你正在使用card_view params,不要。

<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"
>

答案 2 :(得分:9)

要使用卡片视图获得圆形形状,您可以设置形状属性, android:shape =“ring”
app:cardCornerRadius 应设置为子视图宽度或高度的一半

<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>

答案 3 :(得分:7)

使用

  

shape =“ring”

     

使用相同的layout_height和layout_weight

  

app:cardCornerRadius = layout_height或layout_weight

的一半

例如

<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>

答案 4 :(得分:5)

我尝试了你的代码,发现卡片在卡片高度值增加方面不那么圆。尝试将其设置为,这至少使它看起来更好。

card_view:cardElevation="0dp";

但可能更好的选择是使用FloatingActionButton作为圆形按钮

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

答案 5 :(得分:5)

我提出了使用Drawable的简单解决方案,它看起来很神奇!

在这里获取Drawable https://drive.google.com/open?id=0B4Vo_ku-aIKzUFFnUjYxYVRLaGc

enter image description here

答案 6 :(得分:3)

 [
  {
    "Key": "file/ERROR-FILE1-123.xlsx",
  },
  {
    "Key": "file/SUCCESS-FILE2-111.xlsx",
  },
  {
    "Key": "file/PROCESS-FILE3-121.xlsx",
  },
 ]

答案 7 :(得分:1)

是的,我通过将CardCornerRadius的一半减小到其视图的高度来实现它。

答案 8 :(得分:1)

首先将drawbleToolBox库导入您的项目中。 使用此库,您可以动态创建可绘制对象。

  

要使您的卡片视图圆半径等于其高度/宽度的一半。

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

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



                holder.cardView.setBackground(drawable);

如果您在回收站视图中使用cardview,则获取cardview宽度无效 因为它还没有创建。所以你应该做下面的事情

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

答案 9 :(得分:0)

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);
    }


}

答案 10 :(得分:0)

使用CardView获取带有阴影的圆形背景可能会很麻烦,因此请在drawable中使用layer-list获得所需的输出。

<?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>

答案 11 :(得分:0)

将此行添加到将 cardCornerRadius 设置为 Circle 直径的 CardView

app:cardCornerRadius="360dp"