在Android中,ImageView默认是一个矩形。如何使它成为一个圆角矩形(剪辑我的位图的所有4个角为圆角矩形)在ImageView?


请注意,从2021年起,只需使用ShapeableImageView


当前回答

通过使用下面的代码,您可以改变顶部角半径

val image = findViewById<ImageView>(R.id.image)
val curveRadius = 20F

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {

    image.outlineProvider = object : ViewOutlineProvider() {

        @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
        override fun getOutline(view: View?, outline: Outline?) {
            outline?.setRoundRect(0, 0, view!!.width, (view.height+curveRadius).toInt(), curveRadius)
        }
    }

    image.clipToOutline = true

}

其他回答

因为所有的答案对我来说都太复杂了,只是为了圆角,我想到了另一个解决方案,我认为值得分享,只是XML,以防你在图像周围有一些空间:

创建一个带有透明内容的带边框的形状,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners 
        android:radius="30dp" />
    <stroke 
        android:color="#ffffffff"
        android:width="10dp" />
</shape> 

然后在RelativeLayout中,你可以先放置你的图像,然后在相同的位置上面的形状与另一个ImageView。封面形状的大小应与边框宽度相等。注意,要取一个较大的角半径,因为外半径已被定义,但内半径是覆盖你的图像。

希望它也能帮助到别人。

根据CQM请求编辑相关布局示例:

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

    <ImageView
        android:id="@+id/imageToShow"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/imgCorners"
        android:layout_alignLeft="@+id/imgCorners"
        android:layout_alignRight="@+id/imgCorners"
        android:layout_alignTop="@+id/imgCorners"
        android:background="#ffffff"
        android:contentDescription="@string/desc"
        android:padding="5dp"
        android:scaleType="centerCrop" />

    <ImageView
        android:id="@+id/imgCorners"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:contentDescription="@string/desc"
        android:src="@drawable/corners_white" />

</RelativeLayout>

在API 21的View类中添加了对圆形形状的剪切。

只要这样做:

创建一个可绘制的圆形形状,就像这样:

res - drawable round_outline xml。

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>

设置drawable作为ImageView的背景: android:背景= " @drawable / round_outline” 根据这个文档,那么你所需要做的就是添加android:clipToOutline="true"

不幸的是,有一个错误,无法识别该XML属性。幸运的是,我们仍然可以在Java中设置剪辑:

在你的活动或片段中:

下面是它的样子:

注意:

此方法适用于任何可绘制的形状(不仅仅是圆角)。它会剪辑ImageView到你在Drawable xml中定义的任何形状轮廓。

关于ImageViews的特别说明

setClipToOutline()仅在视图的背景设置为可绘制的形状时才有效。如果此背景形状存在,视图将形状的轮廓作为剪切和阴影目的的边界。

这意味着,如果你想使用setClipToOutline()圆角的ImageView,你的图像必须设置使用android:src而不是android:background(因为背景必须设置为您的圆角形状)。如果你必须使用背景来设置你的图像而不是src,你可以使用这个解决方案:

创建一个布局,并将其背景设置为可绘制的形状 将布局包装在ImageView周围(没有填充) ImageView(包括布局中的任何其他内容)现在将以圆角布局形状显示。

虽然上面的答案是可行的,Romain Guy(核心Android开发人员)在他的博客中展示了一个更好的方法,通过使用着色器而不是创建位图的副本来使用更少的内存。该功能的一般要点如下:

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

Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);

RectF rect = new RectF(0.0f, 0.0f, width, height);

// rect contains the bounds of the shape
// radius is the radius in pixels of the rounded corners
// paint contains the shader that will texture the shape
canvas.drawRoundRect(rect, radius, radius, paint);

与其他方法相比,这种方法的优点是:

不创建一个单独的位图副本,对于大图像使用大量内存[相对于这里的大多数其他答案] 支持反锯齿[vs clipPath方法] 支持alpha [vs xfermode+porterduff方法] 支持硬件加速[vs clipPath方法] 只在画布上绘制一次[相对于xfermode和clippath方法]

我创建了一个基于这段代码的RoundedImageView,它将这个逻辑包装到一个ImageView中,并添加了适当的ScaleType支持和可选的圆角边框。

在支持库的v21中,现在有了一个解决方案:它被称为RoundedBitmapDrawable。

它基本上就像一个普通的Drawable,除了你给它一个角半径的剪辑:

setCornerRadius(float cornerRadius)

所以,从Bitmap src和一个目标ImageView开始,它看起来像这样:

RoundedBitmapDrawable dr = RoundedBitmapDrawableFactory.create(res, src);
dr.setCornerRadius(cornerRadius);
imageView.setImageDrawable(dr);

我已经通过自定义ImageView完成:

public class RoundRectCornerImageView extends ImageView {

    private float radius = 18.0f;
    private Path path;
    private RectF rect;

    public RoundRectCornerImageView(Context context) {
        super(context);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public RoundRectCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        path = new Path();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        path.addRoundRect(rect, radius, radius, Path.Direction.CW);
        canvas.clipPath(path);
        super.onDraw(canvas);
    }
}

使用方法:

<com.mypackage.RoundRectCornerImageView
     android:id="@+id/imageView"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@drawable/image"
     android:scaleType="fitXY" />

输出:

希望这对你有所帮助。