<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Background color -->
<solid android:color="@color/white" />
<!-- Stroke around the background, width and color -->
<stroke android:width="4dp" android:color="@color/drop_shadow"/>
<!-- The corners of the shape -->
<corners android:radius="4dp"/>
<!-- Padding for the background, e.g the Text inside a TextView will be
located differently -->
<padding android:left="10dp" android:right="10dp"
android:bottom="10dp" android:top="10dp" />
</shape>
/**
* shows a bitmap as if it had rounded corners. based on :
* http://rahulswackyworld.blogspot.co.il/2013/04/android-drawables-with-rounded_7.html
* easy alternative from support library: RoundedBitmapDrawableFactory.create( ...) ;
*/
public class RoundedCornersDrawable extends BitmapDrawable {
private final BitmapShader bitmapShader;
private final Paint p;
private final RectF rect;
private final float borderRadius;
public RoundedCornersDrawable(final Resources resources, final Bitmap bitmap, final float borderRadius) {
super(resources, bitmap);
bitmapShader = new BitmapShader(getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
final Bitmap b = getBitmap();
p = getPaint();
p.setAntiAlias(true);
p.setShader(bitmapShader);
final int w = b.getWidth(), h = b.getHeight();
rect = new RectF(0, 0, w, h);
this.borderRadius = borderRadius < 0 ? 0.15f * Math.min(w, h) : borderRadius;
}
@Override
public void draw(final Canvas canvas) {
canvas.drawRoundRect(rect, borderRadius, borderRadius, p);
}
}
CustomView.java
public class CustomView extends ImageView {
private View mMainContainer;
private boolean mIsDirty=false;
// TODO for each change of views/content, set mIsDirty to true and call invalidate
@Override
protected void onDraw(final Canvas canvas) {
if (mIsDirty) {
mIsDirty = false;
drawContent();
return;
}
super.onDraw(canvas);
}
/**
* draws the view's content to a bitmap. code based on :
* http://nadavfima.com/android-snippet-inflate-a-layout-draw-to-a-bitmap/
*/
public static Bitmap drawToBitmap(final View viewToDrawFrom, final int width, final int height) {
// Create a new bitmap and a new canvas using that bitmap
final Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bmp);
viewToDrawFrom.setDrawingCacheEnabled(true);
// Supply measurements
viewToDrawFrom.measure(MeasureSpec.makeMeasureSpec(canvas.getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(canvas.getHeight(), MeasureSpec.EXACTLY));
// Apply the measures so the layout would resize before drawing.
viewToDrawFrom.layout(0, 0, viewToDrawFrom.getMeasuredWidth(), viewToDrawFrom.getMeasuredHeight());
// and now the bmp object will actually contain the requested layout
canvas.drawBitmap(viewToDrawFrom.getDrawingCache(), 0, 0, new Paint());
return bmp;
}
private void drawContent() {
if (getMeasuredWidth() <= 0 || getMeasuredHeight() <= 0)
return;
final Bitmap bitmap = drawToBitmap(mMainContainer, getMeasuredWidth(), getMeasuredHeight());
final RoundedCornersDrawable drawable = new RoundedCornersDrawable(getResources(), bitmap, 15);
setImageDrawable(drawable);
}
}
17 回答
使用CardView可以获得任何布局的圆角边缘 . 使用 card_view:cardCornerRadius="5dp" for cardview获取圆角布局边缘 .
For API 21+, Use Clip Views
已修改的轮廓剪辑已添加到API 21中的
View
类 . 有关详细信息,请参阅training doc或此reference .这种内置功能使圆角非常容易实现 . 它适用于任何视图或布局,并支持正确剪切 .
Here's What To Do:
创建一个圆形的drawable并将其设置为视图的背景:
android:background="@drawable/round_outline"
根据文档,您需要做的就是:
android:clipToOutline="true"
不幸的是,似乎有a bug,目前无法识别此XML属性 . 幸运的是,我们可以在Java中设置剪辑:
View.setClipToOutline(true)
What It Looks Like:
Special Note About ImageViews
setClipToOutline()
仅在查看's background is set to a shape drawable. If this background shape exists, View treats the background' s轮廓作为剪裁和阴影用途的边框时有效 .这意味着如果要使用
setClipToOutline()
对ImageView上的角进行圆角处理,则图像必须来自android:src
而不是android:background
(因为背景用于圆角形状) . 如果必须使用背景来设置图像而不是src,则可以使用此嵌套视图解决方法:创建外部布局,其背景设置为可绘制的形状
在ImageView周围换行布局(没有填充)
ImageView(包括布局中的任何其他内容)现在将被剪裁为外部布局的圆形形状 .
最好和最简单的方法是在布局中使用 card_background drawable . 这也符合Google的材料设计指南 . 只需在你的LinearLayout中包含它:
将其添加到您的drawable目录并将其命名为 card_background.xml :
这是一个XML文件的副本,用于创建具有白色背景,黑色边框和圆角的drawable:
将它保存为可绘制目录中的xml文件,使用它就像使用其资源名称(R.drawable.your_xml_name)使用任何可绘制背景(图标或资源文件)一样
更好的方法是:
background_activity.xml
这也适用于API 21,并给你这样的东西:
如果你愿意更多努力更好地控制,那么使用
android.support.v7.widget.CardView
及其cardCornerRadius
属性(并将elevation
属性设置为0dp
以消除任何随附的带有cardView的阴影) . 此外,这将从API级别低至15 .@David,只需将填充值与笔划相同,因此边框可见,无图像大小
如果您想使您的布局四舍五入,最好使用CardView,它提供了许多功能,使设计美观 .
使用此card_view:cardCornerRadius =“5dp”,您可以更改半径 .
我已经将@gauravsapiens的答案与我的评论内容相提并论,让您对参数的影响有一个合理的理解 .
如果你只是想创建一个圆角的形状,删除填充和笔划就可以了 . 如果你也删除了实体,你实际上会在透明背景上创建圆角 .
为了懒惰我在下面创造了一个形状,这只是一个圆角的纯白色背景 - 享受! :)
Inteml的xml
使用(代码中):
1:在drawables中定义 layout_bg.xml :
2:添加
layout_bg.xml
作为布局的背景在drawable,layout_background.xml中创建xml
< - 宽度,颜色,半径应符合您的要求 - >
最后在你的layout.xml文件中写下以下行
我认为更好的方法是合并两件事:
制作布局的位图,如here所示 .
从位图中创建一个圆形的drawable,如图所示here
在imageView上设置drawable .
这将处理其他解决方案无法解决的情况,例如具有角落的内容 .
我认为它对GPU更友好,因为它显示的是单层而不是2层 .
唯一更好的方法是制作一个完全自定义的视图,但这是很多代码,可能需要花费很多时间 . 我认为我在这里建议的是两个世界中最好的 .
这是一个如何完成它的片段:
RoundedCornersDrawable.java
CustomView.java
编辑:基于"RoundKornersLayouts" library找到了一个不错的选择 . 有一个将用于所有要扩展的布局类的类,要进行舍入:
然后,在每个自定义布局类中,添加与此类似的代码:
如果您希望支持属性,请使用库中所写的:
另一种替代方案,对于大多数用途可能更容易:使用MaterialCardView . 它允许自定义圆角,笔触颜色和宽度以及高程 .
例:
结果如下:
请注意,如果您使用它,笔划的边缘会出现轻微的瑕疵(留下内容的某些像素) . 如果你放大,你可以注意到它 . 我已经报道了这个问题here .
试试这个...
1.create drawable xml (custom_layout.xml):
2.添加您的视图背景
在android v7支持库中使用CardView . 虽然它有点重,但它解决了所有问题,而且很容易 . 与set drawable background方法不同,它可以成功剪辑子视图 .
以编程方式设定角半径的功能
运用
我这样做了:
检查截图:
在 drawable 文件夹中创建以
custom_rectangle.xml
命名的 drawable 文件:现在在 View 上申请 Rectangle background :
Done