如何制作带圆角的ImageView?

时间:2010-03-17 04:32:53

标签: android imageview android-imageview android-image rounded-corners

在Android中,默认情况下ImageView是一个矩形。如何在ImageView中将其设置为圆角矩形(将我的Bitmap的所有4个角切掉为圆角矩形)?

55 个答案:

答案 0 :(得分:527)

这已经很晚了,但对于其他正在寻找此问题的人,您可以执行以下代码来手动围绕图像的角落。

http://www.ruibm.com/?p=184

这不是我的代码,但我已经使用过了,它的功能非常好。我在ImageHelper类中使用它作为帮助器,并将它扩展了一点,以传递给定图像所需的羽化量。

最终代码如下所示:

package com.company.app.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;

public class ImageHelper {
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        final float roundPx = pixels;

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }
}

希望这有助于某人!

答案 1 :(得分:200)

虽然上述答案有效,但Romain Guy(核心Android开发人员)在他的博客中显示a better method,该博客使用着色器而不是创建位图副本而使用更少的内存。功能的一般要点是:

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

这比其他方法的优点是:

  • 不创建位图的单独副本,它使用大量内存和大图像[与此处大多数其他答案相比]
  • 支持 antialisasing [vs clipPath method]
  • 支持 alpha [vs xfermode + porterduff method]
  • 支持硬件加速 [vs clipPath method]
  • 只有一次画到画布 [vs xfermode和clippath方法]

我根据此代码创建了一个RoundedImageView,将此逻辑封装到ImageView中,并添加了正确的ScaleType支持和可选的圆角边框。

答案 2 :(得分:130)

另一种简单的方法是使用角半径和内部ImageView的CardView:

  <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:cardCornerRadius="8dp"
            android:layout_margin="5dp"
            android:elevation="10dp">

            <ImageView
                android:id="@+id/roundedImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/image"
                android:background="@color/white"
                android:scaleType="centerCrop"
                />
        </android.support.v7.widget.CardView>

enter image description here

答案 3 :(得分:116)

在支持库的v21中,现在有一个解决方案:它叫做RoundedBitmapDrawable

它基本上就像普通的Drawable一样,除非你给它一个角落半径用于裁剪:

setCornerRadius(float cornerRadius)

因此,从Bitmap src和目标ImageView开始,它看起来像这样:

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

答案 4 :(得分:92)

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

这样做:

  • 创建一个圆形的drawable,如下所示:

RES /抽拉/ round_outline.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="10dp" />
    ...
</shape>
  • 将drawable设置为ImageView的背景: android:background="@drawable/round_outline"
  • 根据此documentation,您需要做的就是添加android:clipToOutline="true"

不幸的是,有a bug并且无法识别XML属性。幸运的是,我们仍然可以在Java中设置剪辑:

  • 在您的活动或片段中:ImageView.setClipToOutline(true)

以下是它的样子:

enter image description here

注意:

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

关于ImageViews的特别说明

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

这意味着,如果您想使用setClipToOutline()围绕ImageView的角落,则必须使用android:src代替android:background来设置您的图片(因为背景必须设置为您的圆形)。如果必须使用背景来设置图像而不是src,则可以使用此解决方法:

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

答案 5 :(得分:56)

Material Components Library的版本 ttree.pandas.df 开始,有一个新的 1.2.0-alpha03

您可以使用类似的内容:

ShapeableImageView

具有:

  <com.google.android.material.imageview.ShapeableImageView
      ...
      app:shapeAppearanceOverlay="@style/roundedImageView"
      app:srcCompat="@drawable/ic_image" />

或以编程方式:

  <style name="roundedImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">8dp</item>
  </style>

enter image description here

答案 6 :(得分:53)

我已经完成了Custom 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" />

<强>输出:

enter image description here

希望这会对你有所帮助。

答案 7 :(得分:53)

我发现这两种方法对于提出有效的解决方案非常有帮助。这是我的复合版本,它是像素独立的,允许你有一些方角,其余的角具有相同的半径(这是通常的用例)。 感谢上述两种解决方案:

public static Bitmap getRoundedCornerBitmap(Context context, Bitmap input, int pixels , int w , int h , boolean squareTL, boolean squareTR, boolean squareBL, boolean squareBR  ) {

    Bitmap output = Bitmap.createBitmap(w, h, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);
    final float densityMultiplier = context.getResources().getDisplayMetrics().density;

    final int color = 0xff424242;
    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, w, h);
    final RectF rectF = new RectF(rect);

    //make sure that our rounded corner is scaled appropriately
    final float roundPx = pixels*densityMultiplier;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);


    //draw rectangles over the corners we want to be square
    if (squareTL ){
        canvas.drawRect(0, h/2, w/2, h, paint);
    }
    if (squareTR ){
        canvas.drawRect(w/2, h/2, w, h, paint);
    }
    if (squareBL ){
        canvas.drawRect(0, 0, w/2, h/2, paint);
    }
    if (squareBR ){
        canvas.drawRect(w/2, 0, w, h/2, paint);
    }


    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
    canvas.drawBitmap(input, 0,0, paint);

    return output;
}

另外,我重写了ImageView,因此我可以在xml中定义它。 你可能想要添加超级​​调用在这里制作的一些逻辑,但我已经对它进行了评论,因为它对我的情况没有帮助。

    @Override
protected void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
        Drawable drawable = getDrawable();

        Bitmap b =  ((BitmapDrawable)drawable).getBitmap() ;
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();


        Bitmap roundBitmap =  CropImageView.getRoundedCornerBitmap( getContext(), bitmap,10 , w, h , true, false,true, false);
        canvas.drawBitmap(roundBitmap, 0,0 , null);
}

希望这有帮助!

答案 8 :(得分:46)

使用ImageLoader here

的圆角图像

创建DisplayImageOptions

DisplayImageOptions options = new DisplayImageOptions.Builder()
    // this will make circle, pass the width of image 
    .displayer(new RoundedBitmapDisplayer(getResources().getDimensionPixelSize(R.dimen.image_dimen_menu))) 
    .cacheOnDisc(true)
    .build();

imageLoader.displayImage(url_for_image,ImageView,options);

或者您可以从Square使用Picasso图书馆。

Picasso.with(mContext)
    .load(com.app.utility.Constants.BASE_URL+b.image)
    .placeholder(R.drawable.profile)
    .error(R.drawable.profile)
    .transform(new RoundedTransformation(50, 4))
    .resizeDimen(R.dimen.list_detail_image_size, R.dimen.list_detail_image_size)
    .centerCrop()
    .into(v.im_user);

您可以在此处下载RoundedTransformation文件 here

答案 9 :(得分:25)

由于所有的答案对于我来说似乎太复杂了,我认为并且找到了另一种我认为值得分享的解决方案,只是在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>

答案 10 :(得分:16)

一种快速的xml解决方案-

export class UserProfileComponent implements OnInit {

    constructor(
        private authService: AuthenticationService,
        private sanitizer: DomSanitizer,
        public dialogService: DialogService,
        private cdRef: ChangeDetectorRef,
        private userService: UserService,
    ) { }

    ngOnInit(): void {

        this.userService.currentMessage.subscribe(message => {
            debugger
            this.message = message;
        });
    }
}


export class ProfileComponent implements OnInit {
    constructor(
        private formBuilder: FormBuilder,
        private userService: UserService,
        private cdRef: ChangeDetectorRef,
        public dialogService: DialogService,
        private sanitizer: DomSanitizer,

    ) { }
    onFileChanged(event: any) {
        this.userService.changeMessage('Hello from Sibling')
    }
}

export class UserService {

    private messageSource = new BehaviorSubject('default message');
    currentMessage = this.messageSource.asObservable();

    changeMessage(message: string) {
        this.messageSource.next(message);
    }
}

您可以在CardView上设置所需的宽度,高度和半径,并在ImageView上设置scaleType。

答案 11 :(得分:14)

我使用圆角小工具实现ImageView,(向下||向上)将图像大小调整为所需尺寸。它使用代码形式CaspNZ。

public class ImageViewRounded extends ImageView {

    public ImageViewRounded(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onDraw(Canvas canvas) {
        BitmapDrawable drawable = (BitmapDrawable) getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return; 
        }

        Bitmap fullSizeBitmap = drawable.getBitmap();

        int scaledWidth = getMeasuredWidth();
        int scaledHeight = getMeasuredHeight();

        Bitmap mScaledBitmap;
        if (scaledWidth == fullSizeBitmap.getWidth() && scaledHeight == fullSizeBitmap.getHeight()) {
            mScaledBitmap = fullSizeBitmap;
        } else {
            mScaledBitmap = Bitmap.createScaledBitmap(fullSizeBitmap, scaledWidth, scaledHeight, true /* filter */);
        }

        Bitmap roundBitmap = ImageUtilities.getRoundedCornerBitmap(getContext(), mScaledBitmap, 5, scaledWidth, scaledHeight,
                false, false, false, false);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

}

答案 12 :(得分:10)

截至最近,还有另一种方法 - 使用Glide's Generated API。它需要一些初步的工作,但随后给你Glide的所有功能,可以灵活地做任何事情,因为你写了实际的代码,所以我认为从长远来看这是一个很好的解决方案。此外,使用非常简单和整洁。

首先,设置Glide版本4 +:

public Optional<SearchRequestBuilder> getRequestBuilderByQuery(SearchQuery query) {
        SearchRequestBuilder builder = getBuilderWithMaxHits(query.getMaxHits());
        builder.setFetchSource(Globals.getFIELDS(query.isIncludeStory()), new String[0]);
        parseQuery(query.getQuery()).ifPresent(builder::setQuery);
        return Optional.of(builder);
    }

然后创建Glid的app模块类以触发注释处理:

implementation 'com.github.bumptech.glide:glide:4.6.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.6.1'

然后创建实际完成工作的Glide扩展。您可以自定义它以执行任何操作:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

添加这些文件后,构建您的项目。

然后在你的代码中使用它:

@GlideExtension
public class MyGlideExtension {

    private MyGlideExtension() {}

    @NonNull
    @GlideOption
    public static RequestOptions roundedCorners(RequestOptions options, @NonNull Context context, int cornerRadius) {
        int px = Math.round(cornerRadius * (context.getResources().getDisplayMetrics().xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return options.transforms(new RoundedCorners(px));
    }
}

答案 13 :(得分:8)

有一个cool library,可让您调整图像视图的形状。

这里是一个例子:

<com.github.siyamed.shapeimageview.mask.PorterShapeImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:siShape="@drawable/shape_rounded_rectangle"
    android:src="@drawable/neo"
    app:siSquare="true"/>

形状定义:

<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:topLeftRadius="18dp"
        android:topRightRadius="18dp"
        android:bottomLeftRadius="18dp"
        android:bottomRightRadius="18dp" />
    <solid android:color="@color/black" />
</shape>

结果:

result

答案 14 :(得分:7)

您应该扩展ImageView并绘制自己的圆角矩形。

如果您想在图像周围使用框架,您还可以将圆形框架叠加在布局中的图像视图顶部。

[edit]例如,使用FrameLayout将帧叠加到原始图像上。 FrameLayout的第一个元素是您想要四舍五入的图像。然后在框架中添加另一个ImageView。第二个ImageView将显示在原始ImageView之上,因此Android会将其内容绘制在原始ImageView上方。

答案 15 :(得分:6)

为什么不在draw()中剪裁?

这是我的解决方案:

  • 使用剪辑
  • 扩展RelativeLayout
  • 将ImageView(或其他视图)放入布局:

代码:

public class RoundRelativeLayout extends RelativeLayout {

private final float radius;

public RoundRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray attrArray = context.obtainStyledAttributes(attrs,
            R.styleable.RoundRelativeLayout);
    radius = attrArray.getDimension(
            R.styleable.RoundRelativeLayout_radius, 0);
}

private boolean isPathValid;
private final Path path = new Path();

private Path getRoundRectPath() {
    if (isPathValid) {
        return path;
    }

    path.reset();

    int width = getWidth();
    int height = getHeight();
    RectF bounds = new RectF(0, 0, width, height);

    path.addRoundRect(bounds, radius, radius, Direction.CCW);
    isPathValid = true;
    return path;
}

@Override
protected void dispatchDraw(Canvas canvas) {
    canvas.clipPath(getRoundRectPath());
    super.dispatchDraw(canvas);
}

@Override
public void draw(Canvas canvas) {
    canvas.clipPath(getRoundRectPath());
    super.draw(canvas);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int oldWidth = getMeasuredWidth();
    int oldHeight = getMeasuredHeight();
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int newWidth = getMeasuredWidth();
    int newHeight = getMeasuredHeight();
    if (newWidth != oldWidth || newHeight != oldHeight) {
        isPathValid = false;
    }
}
}

答案 16 :(得分:6)

Romain Guy就在这里。

缩小版本如下。

Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.image)).getBitmap();

Bitmap bitmapRounded = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
Canvas canvas = new Canvas(bitmapRounded);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.drawRoundRect((new RectF(0.0f, 0.0f, bitmap.getWidth(), bitmap.getHeight())), 10, 10, paint);

imageView.setImageBitmap(bitmapRounded);

答案 17 :(得分:6)

上面的乔治沃尔特斯二世的道具,我只是采取了他的答案并延长了一点,以支持不同的圆角。这可以进一步优化(一些目标重叠),但不是很多。

我知道这个帖子有点陈旧,但它是谷歌查询如何在Android上绕过ImageViews的最佳结果之一。

/**
 * Use this method to scale a bitmap and give it specific rounded corners.
 * @param context Context object used to ascertain display density.
 * @param bitmap The original bitmap that will be scaled and have rounded corners applied to it.
 * @param upperLeft Corner radius for upper left.
 * @param upperRight Corner radius for upper right.
 * @param lowerRight Corner radius for lower right.
 * @param lowerLeft Corner radius for lower left.
 * @param endWidth Width to which to scale original bitmap.
 * @param endHeight Height to which to scale original bitmap.
 * @return Scaled bitmap with rounded corners.
 */
public static Bitmap getRoundedCornerBitmap(Context context, Bitmap bitmap, float upperLeft,
        float upperRight, float lowerRight, float lowerLeft, int endWidth,
        int endHeight) {
    float densityMultiplier = context.getResources().getDisplayMetrics().density;

    // scale incoming bitmap to appropriate px size given arguments and display dpi
    bitmap = Bitmap.createScaledBitmap(bitmap, 
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), true);

    // create empty bitmap for drawing
    Bitmap output = Bitmap.createBitmap(
            Math.round(endWidth * densityMultiplier),
            Math.round(endHeight * densityMultiplier), Config.ARGB_8888);

    // get canvas for empty bitmap
    Canvas canvas = new Canvas(output);
    int width = canvas.getWidth();
    int height = canvas.getHeight();

    // scale the rounded corners appropriately given dpi
    upperLeft *= densityMultiplier;
    upperRight *= densityMultiplier;
    lowerRight *= densityMultiplier;
    lowerLeft *= densityMultiplier;

    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setColor(Color.WHITE);

    // fill the canvas with transparency
    canvas.drawARGB(0, 0, 0, 0);

    // draw the rounded corners around the image rect. clockwise, starting in upper left.
    canvas.drawCircle(upperLeft, upperLeft, upperLeft, paint);
    canvas.drawCircle(width - upperRight, upperRight, upperRight, paint);
    canvas.drawCircle(width - lowerRight, height - lowerRight, lowerRight, paint);
    canvas.drawCircle(lowerLeft, height - lowerLeft, lowerLeft, paint);

    // fill in all the gaps between circles. clockwise, starting at top.
    RectF rectT = new RectF(upperLeft, 0, width - upperRight, height / 2);
    RectF rectR = new RectF(width / 2, upperRight, width, height - lowerRight);
    RectF rectB = new RectF(lowerLeft, height / 2, width - lowerRight, height);
    RectF rectL = new RectF(0, upperLeft, width / 2, height - lowerLeft);

    canvas.drawRect(rectT, paint);
    canvas.drawRect(rectR, paint);
    canvas.drawRect(rectB, paint);
    canvas.drawRect(rectL, paint);

    // set up the rect for the image
    Rect imageRect = new Rect(0, 0, width, height);

    // set up paint object such that it only paints on Color.WHITE
    paint.setXfermode(new AvoidXfermode(Color.WHITE, 255, AvoidXfermode.Mode.TARGET));

    // draw resized bitmap onto imageRect in canvas, using paint as configured above
    canvas.drawBitmap(bitmap, imageRect, imageRect, paint);

    return output;
}

答案 18 :(得分:6)

在我的情况下,这个纯xml解决方案已经足够了。 http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

修改

简而言之,这就是答案:

在/ res / drawable文件夹中,创建一个frame.xml文件。在其中,我们定义了一个带圆角的简单矩形和一个透明中心。

<?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
         <solid android:color="#00ffffff" />
         <padding android:left="6dp"
            android:top="6dp"
            android:right="6dp"
            android:bottom="6dp" />
         <corners android:radius="12dp" />
         <stroke android:width="6dp" android:color="#ffffffff" />
    </shape>

在布局文件中添加包含标准ImageView的LinearLayout,以及嵌套的FrameLayout。 FrameLayout使用填充和自定义drawable来给出圆角的错觉。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:layout_gravity="center"
    android:gravity="center" 
    android:background="#ffffffff">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="6dp"
        android:src="@drawable/tr"/>

    <FrameLayout 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="6dp"
            android:src="@drawable/tr"/>

        <ImageView 
             android:src="@drawable/frame"
             android:layout_width="match_parent"
             android:layout_height="match_parent" />

    </FrameLayout>

</LinearLayout>

答案 19 :(得分:5)

答案中提供的任何方法都不适合我。如果您的android版本为5.0或更高版本,我发现以下方法可行:

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

                    ViewOutlineProvider provider = new ViewOutlineProvider() {
                        @Override
                        public void getOutline(View view, Outline outline) {
                            int curveRadius = 24;
                            outline.setRoundRect(0, 0, view.getWidth(), (view.getHeight()+curveRadius), curveRadius);
                        }
                    };
                    imageview.setOutlineProvider(provider);
                    imageview.setClipToOutline(true);
        }   

没有定义xml形状,并且上面的代码仅为top创建角,而常规方法将不起作用。如果需要将四个角修圆,请删除:

"+ curveRadius"  

从setRoundRect中的bottom参数开始。您可以通过指定适合您需要的轮廓来进一步扩展形状。检查以下链接:

Android Developer Documentation

答案 20 :(得分:5)

以下内容创建一个圆角矩形布局对象,该对象在放置在其中的任何子对象周围绘制一个圆角矩形。它还演示了如何在不使用布局xml文件的情况下以编程方式创建视图和布局。

package android.example;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MessageScreen extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  int mainBackgroundColor = Color.parseColor("#2E8B57");
  int labelTextColor = Color.parseColor("#FF4500");
  int messageBackgroundColor = Color.parseColor("#3300FF");
  int messageTextColor = Color.parseColor("#FFFF00");

  DisplayMetrics metrics = new DisplayMetrics();
  getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int minMarginSize = Math.round(density * 8);
  int paddingSize = minMarginSize * 2;
  int maxMarginSize = minMarginSize * 4;

  TextView label = new TextView(this);
  /*
   * The LayoutParams are instructions to the Layout that will contain the
   * View for laying out the View, so you need to use the LayoutParams of
   * the Layout that will contain the View.
   */
  LinearLayout.LayoutParams labelLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
  label.setLayoutParams(labelLayoutParams);
  label.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
  label.setPadding(paddingSize, paddingSize, paddingSize, paddingSize);
  label.setText(R.string.title);
  label.setTextColor(labelTextColor);

  TextView message = new TextView(this);
  RoundedRectangle.LayoutParams messageLayoutParams = new RoundedRectangle.LayoutParams(
 LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to put some extra space around the
   * View.
   */
  messageLayoutParams.setMargins(minMarginSize, paddingSize,
    minMarginSize, maxMarginSize);
  message.setLayoutParams(messageLayoutParams);
  message.setTextSize(TypedValue.COMPLEX_UNIT_SP, paddingSize);
  message.setText(R.string.message);
  message.setTextColor(messageTextColor);
  message.setBackgroundColor(messageBackgroundColor);

  RoundedRectangle messageContainer = new RoundedRectangle(this);
  LinearLayout.LayoutParams messageContainerLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  messageContainerLayoutParams.setMargins(paddingSize, 0, paddingSize, 0);
  messageContainer.setLayoutParams(messageContainerLayoutParams);
  messageContainer.setOrientation(LinearLayout.VERTICAL);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This tells the RoundedRectangle to color the the exta space that was
   * put around the View as well as the View. This is exterior color of
   * the RoundedRectangle.
   */
  messageContainer.setBackgroundColor(mainBackgroundColor);
  /*
   * This is one of the calls must made to force a ViewGroup to call its
   * draw method instead of just calling the draw method of its children.
   * This is the interior color of the RoundedRectangle. It must be
   * different than the exterior color of the RoundedRectangle or the
   * RoundedRectangle will not call its draw method.
   */
  messageContainer.setInteriorColor(messageBackgroundColor);
  // Add the message to the RoundedRectangle.
  messageContainer.addView(message);

  //
  LinearLayout main = new LinearLayout(this);
  LinearLayout.LayoutParams mainLayoutParams = new LinearLayout.LayoutParams(
    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
  main.setLayoutParams(mainLayoutParams);
  main.setOrientation(LinearLayout.VERTICAL);
  main.setBackgroundColor(mainBackgroundColor);
  main.addView(label);
  main.addView(messageContainer);

  setContentView(main);
 }
}

RoundedRectangle布局对象的类如下所示:

/**
 *  A LinearLayout that draws a rounded rectangle around the child View that was added to it.
 */
package android.example;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.widget.LinearLayout;

/**
 * A LinearLayout that has rounded corners instead of square corners.
 * 
 * @author Danny Remington
 * 
 * @see LinearLayout
 * 
 */
public class RoundedRectangle extends LinearLayout {
 private int mInteriorColor;

 public RoundedRectangle(Context p_context) {
  super(p_context);
 }

 public RoundedRectangle(Context p_context, AttributeSet attributeSet) {
  super(p_context, attributeSet);
 }

 // Listener for the onDraw event that occurs when the Layout is drawn.
 protected void onDraw(Canvas canvas) {
  Rect rect = new Rect(0, 0, getWidth(), getHeight());
  RectF rectF = new RectF(rect);
  DisplayMetrics metrics = new DisplayMetrics();
  Activity activity = (Activity) getContext();
  activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
  float density = metrics.density;
  int arcSize = Math.round(density * 10);

  Paint paint = new Paint();
  paint.setColor(mInteriorColor);

  canvas.drawRoundRect(rectF, arcSize, arcSize, paint);
 }

 /**
  * Set the background color to use inside the RoundedRectangle.
  * 
  * @param Primitive int - The color inside the rounded rectangle.
  */
 public void setInteriorColor(int interiorColor) {
  mInteriorColor = interiorColor;
 }

 /**
  * Get the background color used inside the RoundedRectangle.
  * 
  * @return Primitive int - The color inside the rounded rectangle.
  */
 public int getInteriorColor() {
  return mInteriorColor;
 }

}

答案 21 :(得分:4)

非常感谢您的回答。这是修改后的版本,将矩形图像转换为方形(并呈圆角),填充颜色作为参数传递。

public static Bitmap getRoundedBitmap(Bitmap bitmap, int pixels, int color) {

    Bitmap inpBitmap = bitmap;
    int width = 0;
    int height = 0;
    width = inpBitmap.getWidth();
    height = inpBitmap.getHeight();

    if (width <= height) {
        height = width;
    } else {
        width = height;
    }

    Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    Canvas canvas = new Canvas(output);

    final Paint paint = new Paint();
    final Rect rect = new Rect(0, 0, width, height);
    final RectF rectF = new RectF(rect);
    final float roundPx = pixels;

    paint.setAntiAlias(true);
    canvas.drawARGB(0, 0, 0, 0);
    paint.setColor(color);
    canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

    paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
    canvas.drawBitmap(inpBitmap, rect, rect, paint);

    return output;
}

答案 22 :(得分:4)

这是一个覆盖imageView的简单示例,您也可以在布局设计器中使用它进行预览。

public class RoundedImageView extends ImageView {
public RoundedImageView(Context context) {
    super(context);
}

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

public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}

@Override
public void setImageDrawable(Drawable drawable) {
    float radius = 0.1f;
    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
    RoundedBitmapDrawable rid = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
    rid.setCornerRadius(bitmap.getWidth() * radius);
    super.setImageDrawable(rid);
}

}

这是为了快速解决方案。 Radius用于所有角落,并基于位图宽度的百分比。

我刚刚覆盖了setImageDrawable并使用了支持v4方法来绘制圆形位图。

用法:

<com.example.widgets.RoundedImageView
        android:layout_width="39dp"
        android:layout_height="39dp"
        android:src="@drawable/your_drawable" />

使用imageView和自定义imageView进行预览:

enter image description here

答案 23 :(得分:4)

将形状应用到imageView,如下所示:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <solid android:color="#faf5e6" />
    <stroke
        android:width="1dp"
        android:color="#808080" />
    <corners android:radius="15dp" />
    <padding
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />
</shape>

这对你的朋友可能有帮助。

答案 24 :(得分:3)

您只能在布局中使用ImageView并使用glide,您可以使用此方法应用圆角。

首先在你的gradle写作

compile 'com.github.bumptech.glide:glide:3.7.0'

适用于带圆角的图片,

public void loadImageWithCorners(String url, ImageView view) {
    Glide.with(context)
            .load(url)
            .asBitmap()
            .centerCrop()
            .placeholder(R.color.gray)
            .error(R.color.gray)
            .diskCacheStrategy(DiskCacheStrategy.SOURCE)
            .into(new BitmapImageViewTarget(view) {
                @Override
                protected void setResource(Bitmap resource) {
                    RoundedBitmapDrawable circularBitmapDrawable =
                            RoundedBitmapDrawableFactory.create(context.getResources(), resource);
                    circularBitmapDrawable.setCornerRadius(32.0f); // radius for corners
                    view.setImageDrawable(circularBitmapDrawable);
                }
            });
}

通话方式:

loadImageWithCorners("your url","your imageview");

答案 25 :(得分:3)

只需要使用androidx.cardview.widget.CardView

代码

<androidx.cardview.widget.CardView
    app:cardElevation="0dp"
    app:cardCornerRadius="16dp"
    android:layout_margin="2dp"
    android:layout_width="match_parent"
    android:layout_height="200dp">
    <androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/ivPanCard"
        android:layout_width="match_parent"
        android:scaleType="centerCrop"
        android:layout_height="200dp"
        />
</androidx.cardview.widget.CardView>

答案 26 :(得分:2)

对于使用Glide和Kotlin的用户,可以通过扩展RequestBuilder

来实现。
fun <T> GlideRequest<T>.roundCorners(cornerRadius: Int) =
    apply(RequestOptions().transform(RoundedCorners(cornerRadius)))

并用作;

 GlideApp.with(context)
            .load(url)
            .roundCorners(context.resources.getDimension(R.dimen.radius_in_dp).toInt())
            .into(imgView)

答案 27 :(得分:2)

回答此处重定向的问题: &#34;如何在Android中创建圆形ImageView?&#34;

public static Bitmap getRoundBitmap(Bitmap bitmap) {

    int min = Math.min(bitmap.getWidth(), bitmap.getHeight());

    Bitmap bitmapRounded = Bitmap.createBitmap(min, min, bitmap.getConfig());

    Canvas canvas = new Canvas(bitmapRounded);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawRoundRect((new RectF(0.0f, 0.0f, min, min)), min/2, min/2, paint);

    return bitmapRounded;
}

答案 28 :(得分:2)

glide库和RoundedBitmapDrawableFactory课程的帮助下,它很容易实现。您可能需要创建圆形占位符图像。

    Glide.with(context)
        .load(imgUrl)
        .asBitmap()
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.placeholder)
        .into(new BitmapImageViewTarget(imgProfilePicture) {
            @Override
            protected void setResource(Bitmap resource) {
                RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(),
                        Bitmap.createScaledBitmap(resource, 50, 50, false));
                drawable.setCornerRadius(10); //drawable.setCircular(true);
                imgProfilePicture.setImageDrawable(drawable);
            }
        });

答案 29 :(得分:2)

如果您的图片在互联网上,最好的方法是使用滑行和RoundedBitmapDrawableFactory(来自API 21 - 但在支持库中可用),如下所示:

 Glide.with(ctx).load(url).asBitmap().centerCrop().into(new BitmapImageViewTarget(imageView) {
    @Override
    protected void setResource(Bitmap res) {
        RoundedBitmapDrawable bitmapDrawable =
             RoundedBitmapDrawableFactory.create(ctx.getResources(), res);
        bitmapDrawable.setCircular(true);//comment this line and uncomment the next line if you dont want it fully cricular
        //circularBitmapDrawable.setCornerRadius(cornerRadius);
        imageView.setImageDrawable(bitmapDrawable);
    }
});

答案 30 :(得分:2)

<强>科特林

import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*

val bitmap = BitmapFactory.decodeResource(resources, R.drawable.myImage)
val rounded = RoundedBitmapDrawableFactory.create(resources, bitmap)
rounded.cornerRadius = 20f
profileImageView.setImageDrawable(rounded)

ImageView通知,我们可以使用以下内容更改cornerRadius

rounded.isCircular = true

答案 31 :(得分:1)

我认为最简单的解决方案是这样的:-

第1步-创建如下形状的可绘制文件:-

<?xml version="1.0" encoding="utf-8"?>

<solid android:color="@color/white" />

<corners android:radius="@dimen/dimen_10dp" />

<stroke
    android:width="1dp"
    android:color="@color/white" />

第2步-在代码中使用上述drawable。

Drawable drawable = ContextCompat.getDrawable(mActivity, R.drawable.photos_round_shape);
            drawable.mutate().setColorFilter(randomColor, PorterDuff.Mode.SRC_ATOP);
            imageView.setBackground(drawable);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
               imageView.setClipToOutline(true);
            }

Glide.with(mContext)
                .setDefaultRequestOptions(getNoAnimationOptions())
                .load(url)
                .into(imageView);

希望这会有所帮助。

答案 32 :(得分:1)

我正在使用自定义视图,我在其他视图上进行布局,只绘制与背景颜色相同的4个小倒角

优点:

  • 不分配位图。
  • 无论您想要应用圆角的视图都可以使用。
  • 适用于所有 API级别;)

代码:

public class RoundedCornersView extends View {
    private float mRadius;
    private int mColor = Color.WHITE;
    private Paint mPaint;
    private Path mPath;

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

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

        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.RoundedCornersView,
                0, 0);

        try {
            setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
            setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
        } finally {
            a.recycle();
        }
    }

    private void init() {
        setColor(mColor);
        setRadius(mRadius);
    }

    private void setColor(int color) {
        mColor = color;
        mPaint = new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        invalidate();
    }

    private void setRadius(float radius) {
        mRadius = radius;
        RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
        mPath = new Path();
        mPath.moveTo(0,0);
        mPath.lineTo(0, mRadius);
        mPath.arcTo(r, 180, 90);
        mPath.lineTo(0,0);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        /*This just draws 4 little inverted corners */

        int w = getWidth();
        int h = getHeight();
        canvas.drawPath(mPath, mPaint);
        canvas.save();
        canvas.translate(w, 0);
        canvas.rotate(90);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.save();
        canvas.translate(w, h);
        canvas.rotate(180);
        canvas.drawPath(mPath, mPaint);
        canvas.restore();
        canvas.translate(0, h);
        canvas.rotate(270);
        canvas.drawPath(mPath, mPaint);
    }
}

答案 33 :(得分:1)

很多答案!

我按照这个例子,也有一些人有点建议:http://www.techrepublic.com/article/pro-tip-round-corners-on-an-android-imageview-with-this-hack/

但是,我需要的是一个彩色圆圈,在透明图像后面。对于有兴趣做同样事情的人......

1)将FrameLayout设置为宽度和高度 - 在我的例子中是图像的大小(50dp)。
2)将具有src =&#34; @drawable /..."的ImageView放置在具有图像的ImageView上方。给它一个id,在我的情况下我称之为iconShape
3)Drawable mask.xml应该是#ffffffff的纯色 4)如果要动态更改代码中的圆形颜色,请执行

ImageView iv2 = (ImageView) v.findViewById(R.id.iconShape);
Drawable shape = getResources().getDrawable(R.drawable.mask);
shape.setColorFilter(Color.BLUE, Mode.MULTIPLY);
iv2.setImageDrawable(shape);

答案 34 :(得分:1)

您可以尝试使用此库 - RoundedImageView

是:

  

支持圆角,椭圆和圆形的快速ImageView。 CircleImageView的完整超集。

我在我的项目中使用过它,非常简单。

答案 35 :(得分:1)

使用此选项获取带边框的圆形图像 -

    public static Bitmap getCircularBitmapWithBorder(Bitmap bitmap, int bordercolor) {
    if (bitmap == null || bitmap.isRecycled()) {
        return null;
    }
    int borderWidth=(int)(bitmap.getWidth()/40);
    final int width = bitmap.getWidth() + borderWidth;
    final int height = bitmap.getHeight() + borderWidth;

    Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
            Bitmap.Config.ARGB_8888);
    BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP,
            TileMode.CLAMP);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    paint.setShader(shader);

    Canvas canvas = new Canvas(canvasBitmap);
    float radius = width > height ? ((float) height) / 2f
            : ((float) width) / 2f;
    canvas.drawCircle(width / 2, height / 2, radius, paint);
    paint.setShader(null);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(bordercolor);
    paint.setStrokeWidth(borderWidth);
    canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2,
            paint);
    return canvasBitmap;
}

答案 36 :(得分:0)

对我来说,以下解决方案似乎是最优雅的:

ImageView roundedImageView = new ImageView (getContext());
roundedImageView.setClipToOutline(true);
Bitmap bitmap = AppUtil.decodeSampledBitmapFromResource(new File(valueListItemsView.getImagePath()), width, height);
roundedImageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
roundedImageView.setImageBitmap(bitmap);
roundedImageView.setBackgroundResource(R.drawable.rounded_corner);

,并且rounded_corner.xml可绘制代码是:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorAccent" />
    <corners android:radius="24dp" />
</shape>

答案 37 :(得分:0)

我建议在这种情况下使用 Coil 库

<块引用>

Coil 优先使用 Kotlin,并使用现代库,包括 Coroutines、OkHttp、Okio 和 AndroidX Lifecycles。

github link

答案 38 :(得分:0)

您可以使用较新版本的 Android Material 库中提供的新 ShaableImageView

为此,您首先需要在应用级 build.gradle 文件中添加以下依赖项

implementation 'com.google.android.material:material:<version>'

此外,请确保此应用级 build.gradle 文件具有 Google 的 Maven 存储库 google(),如下所示

allprojects {
repositories {
  google()
  jcenter()
}

}

现在,您可以参考 this 资源来实现您想要的类型或形状的图像视图。

答案 39 :(得分:0)

圆角边框使用下面的代码

  <com.google.android.material.card.MaterialCardView
                        android:id="@+id/circle"
                        android:layout_width="45dp"
                        android:layout_height="45dp"
                        android:layout_marginStart="5dp"

                        app:cardCornerRadius="25dp"
                        app:strokeColor="@color/colorDarkGreen"

                        app:strokeWidth="1dp">

                        <ImageView
                            android:id="@+id/toolbarProfile"
                            android:scaleType="fitXY"

                            android:layout_width="match_parent"
                            android:layout_height="match_parent"

                            android:src="@drawable/avater" />
                    </com.google.android.material.card.MaterialCardView>

答案 40 :(得分:0)

这不是答案,但它是一个类似的解决方案。它可能会帮助那些和我在同一条船上的人。

我的图片,一个应用程序徽标,有一个透明的背景,我正在应用XML渐变作为图像背景。我在XML中为imageView添加了必要的填充/边距,然后将其添加为我的背景:

<?xml version="1.0" encoding="utf-8"?>

<item>

    <shape>

        <gradient
            android:type="linear"
            android:startColor="@color/app_color_light_background"
            android:endColor="@color/app_color_disabled"
            android:angle="90"
        />

        <!-- Round the top corners. -->
        <corners
            android:topLeftRadius="@dimen/radius_small"
            android:topRightRadius="@dimen/radius_small"
        />

    </shape>

</item>

答案 41 :(得分:0)

如果您不希望边框影响图像,请使用此类。不幸的是,onDraw()并没有找到在画布上绘制透明区域的任何方法。因此,在这里创建了一个新的位图,并将其绘制在真实的画布上。

如果要使边框消失,该视图将很有用。如果将borderWidth设置为0,则边框将消失并且图像的圆角与边框完全一样。即看起来边框是完全由图像边缘绘制的。

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.RectF
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView


class RoundedImageViewWithBorder @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0) : AppCompatImageView(context, attrs, defStyleAttr) {

    var borderColor: Int = 0
        set(value) {
            invalidate()
            field = value
        }
    var borderWidth: Int = 0
        set(value) {
            invalidate()
            field = value
        }
    var cornerRadius: Float = 0f
        set(value) {
            invalidate()
            field = value
        }

    private var bitmapForDraw: Bitmap? = null
    private var canvasForDraw: Canvas? = null
    private val transparentPaint = Paint().apply {
        isAntiAlias = true
        color = Color.TRANSPARENT
        style = Paint.Style.STROKE
        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC)
    }

    private val borderPaint = Paint().apply {
        isAntiAlias = true
        style = Paint.Style.STROKE
    }

    private val transparentAreaRect = RectF()
    private val borderRect = RectF()

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageViewWithBorder)

        try {
            borderWidth = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_border_width, 0)
            borderColor = typedArray.getColor(R.styleable.RoundedImageViewWithBorder_border_color, 0)
            cornerRadius = typedArray.getDimensionPixelSize(R.styleable.RoundedImageViewWithBorder_corner_radius, 0).toFloat()

        } finally {
            typedArray.recycle()
        }
    }

    @SuppressLint("CanvasSize", "DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        if (canvas.height <=0 || canvas.width <=0) {
            return
        }

        if (canvasForDraw?.height != canvas.height || canvasForDraw?.width != canvas.width) {
            val newBitmap = Bitmap.createBitmap(canvas.width, canvas.height, Bitmap.Config.ARGB_8888)
            bitmapForDraw = newBitmap
            canvasForDraw = Canvas(newBitmap)
        }
        
        bitmapForDraw?.eraseColor(Color.TRANSPARENT)

        // Draw existing content
        super.onDraw(canvasForDraw)

        if (borderWidth > 0) {
            canvasForDraw?.let { drawWithBorder(it) }
        } else {
            canvasForDraw?.let { drawWithoutBorder(it) }
        }

        // Draw everything on real canvas
        bitmapForDraw?.let { canvas.drawBitmap(it, 0f, 0f, null) }
    }

    private fun drawWithBorder(canvas: Canvas) {
        // Draw transparent area
        transparentPaint.strokeWidth = borderWidth.toFloat() * 4
        transparentAreaRect.apply {
            left = -borderWidth.toFloat() * 1.5f
            top = -borderWidth.toFloat() * 1.5f
            right = canvas.width.toFloat() + borderWidth.toFloat() * 1.5f
            bottom = canvas.height.toFloat() + borderWidth.toFloat() * 1.5f
        }
        canvasForDraw?.drawRoundRect(transparentAreaRect, borderWidth.toFloat() * 2 + cornerRadius, borderWidth.toFloat() * 2 + cornerRadius, transparentPaint)

        // Draw border
        borderPaint.color = borderColor
        borderPaint.strokeWidth = borderWidth.toFloat()
        borderRect.apply {
            left = borderWidth.toFloat() / 2
            top = borderWidth.toFloat() / 2
            right = canvas.width.toFloat() - borderWidth.toFloat() / 2
            bottom = canvas.height.toFloat() - borderWidth.toFloat() / 2
        }
        canvas.drawRoundRect(borderRect, cornerRadius - borderWidth.toFloat() / 2, cornerRadius - borderWidth.toFloat() / 2, borderPaint)
    }

    private fun drawWithoutBorder(canvas: Canvas) {
        // Draw transparent area
        transparentPaint.strokeWidth = cornerRadius * 4
        transparentAreaRect.apply {
            left = -cornerRadius * 2
            top = -cornerRadius * 2
            right = canvas.width.toFloat() + cornerRadius * 2
            bottom = canvas.height.toFloat() + cornerRadius * 2
        }
        canvasForDraw?.drawRoundRect(transparentAreaRect, cornerRadius * 3, cornerRadius * 3, transparentPaint)
    }

}

值:

<declare-styleable name="RoundedImageViewWithBorder">
    <attr name="corner_radius" format="dimension|string" />
    <attr name="border_width" format="dimension|reference" />
    <attr name="border_color" format="color|reference" />
</declare-styleable>

答案 42 :(得分:0)

可以很容易地完成以下形状。将其作为src添加到图像中。 如果要删除边框,只需将背景色添加到边框 ;-)

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/img_area_one"
        android:bottom="5dp"
        android:left="5dp"
        android:right="5dp"
        android:top="5dp" />

    <item>
        <shape
            android:padding="10dp"
            android:shape="rectangle">
            <corners
                android:topLeftRadius="8dp"
                android:topRightRadius="8dp"
                />
            <stroke
                android:width="5dp"
                android:color="@color/white" />
        </shape>
    </item>
</layer-list> 

答案 43 :(得分:0)

科林版:

@GlideExtension
object GamersGeekGlideExtension {

    @NonNull
    @JvmStatic
    @GlideOption
    fun roundedCorners(options: BaseRequestOptions<*>, context: Context, cornerRadius: Int): BaseRequestOptions<*> {
        val px =
            (cornerRadius * (context.resources.displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT)).roundToInt()
        return options.transforms(RoundedCorners(px))
    }
}

注意:Glide Extensions现在需要BaseRequestOptions而不是RequestOptions。另外,它与@Sir Codesalot答案的功能相同,只是在kotlin中进行了转换。编码愉快。

答案 44 :(得分:0)

感谢melanke,您可以使用自定义类并创建自定义循环ImageView

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;

public class MLRoundedImageView extends android.support.v7.widget.AppCompatImageView {

    public MLRoundedImageView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onDraw(Canvas canvas) {

        Drawable drawable = getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();

        Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
        Bitmap sbmp;

        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }

        Bitmap output = Bitmap.createBitmap(radius, radius,
                Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sbmp, rect, rect, paint);

        return output;
    }

}

然后在XML中使用它:

<your.package.name.MLRoundedImageView
..
/>

Source

答案 45 :(得分:0)

通过使用以下代码,您可以更改上角半径

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

}

答案 46 :(得分:0)

我使用路径仅在图像画布上绘制角(我需要没有位图内存分配的解决方案)。

    @Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);

        if (!hasRoundedCorners()) return;

        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(0);

        Path path = new Path();
        path.setFillType(Path.FillType.INVERSE_WINDING);
        path.addRoundRect(new RectF(0, 0, getWidth(), getHeight()), mRadius, mRadius, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
    }

请注意,您不应在onDraw方法中分配任何新对象。该代码是概念证明,不应在产品代码中像这样使用

查看更多: https://medium.com/@przemek.materna/rounded-image-view-no-bitmap-reallocation-11a8b163484d

答案 47 :(得分:0)

您可以非常容易地使用roundedImageView库:

compile 'com.makeramen:roundedimageview:2.3.0'

然后:

<com.makeramen.roundedimageview.RoundedImageView
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:id="@+id/img_episode"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:elevation="7dp"
  app:riv_border_color="@color/colorPrimary"
  app:riv_border_width="1dip"
  app:riv_corner_radius="10dip"
  app:riv_mutate_background="true"
  />

答案 48 :(得分:0)

对于 Glide 4.x.x

使用此简单代码

Glide
  .with(context)
  .load(uri)
  .apply(
      RequestOptions()
        .circleCrop())
  .into(imageView)

答案 49 :(得分:0)

**In Layout**

Make your ImageView like

   <com.example..CircularImageView
            android:id="@+id/profile_image_round_corner"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:scaleType="fitCenter"
            android:padding="2dp"
            android:background="@null"
            android:adjustViewBounds="true"
            android:layout_centerInParent="true"
            android:src="@drawable/dummy" />



**And Create a Class**

package com.example;

import java.util.Formatter.BigDecimalLayoutForm;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CircularImageView extends ImageView {

    public CircularImageView(Context context) {
        super(context);
    }

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

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

    @Override
    protected void onDraw(Canvas canvas) {

        Drawable drawable = getDrawable();

        if (drawable == null) {
            return;
        }

        if (getWidth() == 0 || getHeight() == 0) {
            return;
        }
        Bitmap b = ((BitmapDrawable) drawable).getBitmap();
        Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);

        int w = getWidth(), h = getHeight();

        Bitmap roundBitmap = getRoundBitmap(bitmap, w);
        canvas.drawBitmap(roundBitmap, 0, 0, null);

    }

    public static Bitmap getRoundBitmap(Bitmap bmp, int radius) {
        Bitmap sBmp;

        if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
            float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
            float factor = smallest / radius;
            sBmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
        } else {
            sbmp = bmp;
        }

        Bitmap output = Bitmap.createBitmap(radius, radius,
              Bitmap.Config.ARGB_8888);


        Canvas canvas = new Canvas(output);

        final int color = 0xffa19774;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, radius, radius);

        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(radius / 2 + 0.7f,
                radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
        canvas.drawBitmap(sBmp, rect, rect, paint);

        return output;
    }

}

答案 50 :(得分:0)

如果您有任何人遇到此问题

enter image description here

最有可能的是,您使用的是 Android Studio 。由于图像重新调整大小以及Android Studio中的所有内容,您可能会遇到此问题。解决此问题的一个简单方法是减少drawCircle()中的圆的半径。在我的情况下,我使用此修复

使用canvas.drawCircle(100, 100, 90, paint);代替canvas.drawCircle(100, 100, 100, paint);这肯定会解决您的问题。

这是最后编辑的代码: -

  public class Profile extends ActionBarActivity {


    TextView username;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.profile);


        username= (TextView) findViewById(R.id.txt);

        String recievedusername=getIntent().getExtras().getString("toname");
        username.setText(recievedusername);


        Bitmap bm = BitmapFactory.decodeResource(getResources(),
                R.mipmap.gomez);

        Bitmap resizedBitmap = Bitmap.createScaledBitmap(bm, 200,200, false);
        Bitmap conv_bm=getCircleBitmap(resizedBitmap,100);
        // set circle bitmap
        ImageView mImage = (ImageView) findViewById(R.id.profile_image);
        mImage.setImageBitmap(conv_bm);
        // TODO Auto-generated method stub
    }
    private Bitmap getCircleBitmap(Bitmap bitmap , int pixels) {
        final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(),bitmap.getHeight());
        final RectF rectF = new RectF(rect);
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(100,100, 90, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        bitmap.recycle();
        return output;
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_apploud, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_addnew) {
            Intent i;
            i=new Intent(Profile.this,ApplaudSomeone.class);
            startActivity(i);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
}

答案 51 :(得分:0)

试试这个

Bitmap finalBitmap;
        if (bitmap.getWidth() != radius || bitmap.getHeight() != radius)
            finalBitmap = Bitmap.createScaledBitmap(bitmap, radius, radius,
                    false);
        else
            finalBitmap = bitmap;
        Bitmap output = Bitmap.createBitmap(finalBitmap.getWidth(),
                finalBitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, finalBitmap.getWidth(),
                finalBitmap.getHeight());

        paint.setAntiAlias(true);
        paint.setFilterBitmap(true);
        paint.setDither(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(Color.parseColor("#BAB399"));
        canvas.drawCircle(finalBitmap.getWidth() / 2 + 0.7f,
                finalBitmap.getHeight() / 2 + 0.7f,
                finalBitmap.getWidth() / 2 + 0.1f, paint);
        paint.setXfermode(new PorterDuffXfermode(
                android.graphics.PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(finalBitmap, rect, rect, paint);

        return output;

答案 52 :(得分:0)

    /**
 * Background Async task to load user profile picture from url
 */
private class LoadProfileImage extends AsyncTask<String, Void, RoundedBitmapDrawable> {
    ImageView profileImageView;

    public LoadProfileImage(ImageView profileImageView) {
        this.profileImageView = profileImageView;
    }

    protected RoundedBitmapDrawable doInBackground(String... urls) {
        String photoUrl = urls[0];
        RoundedBitmapDrawable profileRoundedDrawable = null;
        try {
            InputStream inputStream = new java.net.URL(photoUrl).openStream();
            Resources res = getResources();

            profileRoundedDrawable = RoundedBitmapDrawableFactory.create(res, inputStream);
            profileRoundedDrawable.setCircular(true);
        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return profileRoundedDrawable;
    }

    protected void onPostExecute(RoundedBitmapDrawable result) {
        profileImageView.setImageDrawable(result);
    }
}

答案 53 :(得分:0)

虽然前两个答案有效,但我想再描述一下。 比如说,你有一个ImageView所在的活动或片段。您希望绘制图像并按比例缩放。然后你应该在onCreate或onCreateView上写下以下内容:

public static int getImageViewHeight(Drawable drawable, ImageView imageView) {
    imageView.setImageDrawable(drawable);
    int width = drawable.getIntrinsicWidth();
    int height = 0;
    if (width > 0) {
        height = (drawable.getIntrinsicHeight() * imageView.getWidth()) / width;
        imageView.getLayoutParams().height = height;
        imageView.requestLayout();
    }
    return height;
}

设置新图像高度的位置是:

private Bitmap getRoundedBitmap(Bitmap bitmap, int width, int height, float radius) {
    // Create scaled bitmap.
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false);
    BitmapShader shader = new BitmapShader(scaledBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

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

    Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(result);
    // First make all corners round.
    canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paint);
    // Then draw bottom rectangle.
    canvas.drawRect(0, height - radius, radius, height, paint);
    canvas.drawRect(width - radius, height - radius, width, height, paint);
    return result;
}

然后你应该写一个方法来缩放图像并绕过它的角。这里宽度和高度是位图的新尺寸(更小或更大)。在以下示例中,我只围绕两个顶角

     "datos_personales":
              {
              "nombre":"Dionel",
              "apellido":"Delgado",
              "fechanacimiento":"1990-12-31T04:00:00.000Z",
              "lugarNacimiento":"Venezuela, Maracaibo",
              "edad":25,
      "genero":"Masculino",
              "cedula":"21076754",
              "direccion":"San Carlos",
              "telefonofijo":"0262-6871111",
              "telefonomovil":"0262-6871111"
               },

      "datos_emergencia":
              {
              "nombre1":"Jeaynie",
              "apellido1":"Valbuena",
              "telefono1":"0262-6871111",
              "telefono2":"0262-6871111",
              "parentesco1":"Madre",
              "nombre2":"Diones",
              "apellido2":"Delgado",
              "telefono3":"0262-6871111",
              "telefono4":"0262-6871111",
              "parentesco2":"Padre"
              },

       "datos_sociales":
             {
             "civil":"Soltero",
             "estudios4":true,
             "ocupacion":"Programador Web",
             "hijos":"No"
             },
       "datos_medicotratante":
             {
             "nombre":"Naikelin",
             "apellido":"Ruiz",
             "telefono1":"0262-6871111",
             "telefono2":"0262-6871111",
             "especialidad":"Pediatría",
             "sangre":"AB",
             "rh":"Negativo",
             "seguro":"No"
              }

答案 54 :(得分:0)

这是我的解决方案:

<com.myproject.ui.RadiusCornerImageView
        android:id="@+id/imageViewPhoto"
        android:layout_width="160dp"
        android:layout_height="160dp"
        app:corner_radius_dp="5"
        app:corner_radius_position="top"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

在java代码中:

public class RadiusCornerImageView extends android.support.v7.widget.AppCompatImageView {
    private int cornerRadiusDP = 0; // dp
    private int corner_radius_position;

    public RadiusCornerImageView(Context context) {
        super(context);
    }

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

    public RadiusCornerImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RadiusCornerImageView, 0, 0);
        try {
            cornerRadiusDP = typeArray.getInt(R.styleable.RadiusCornerImageView_corner_radius_dp, 0);
            corner_radius_position = typeArray.getInteger(R.styleable.RadiusCornerImageView_corner_radius_position, 0);
        } finally {
            typeArray.recycle();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float radiusPx = AndroidUtil.dpToPx(getContext(), cornerRadiusDP);
        Path clipPath = new Path();
        RectF rect = null;
        if (corner_radius_position == 0) { // all
            // round corners on all 4 angles
            rect = new RectF(0, 0, this.getWidth(), this.getHeight());
        } else if (corner_radius_position == 1) {
            // round corners only on top left and top right
            rect = new RectF(0, 0, this.getWidth(), this.getHeight() + radiusPx);

    } else {
        throw new IllegalArgumentException("Unknown corner_radius_position = " + corner_radius_position);
    }
    clipPath.addRoundRect(rect, radiusPx, radiusPx, Path.Direction.CW);
    canvas.clipPath(clipPath);
    super.onDraw(canvas);
}

}