简体   繁体   English

Android中带有圆角的自定义视图

[英]Custom view with rounded corners in Android

I have a custom view which contains several layers of images, layouts with texts, drawings etc. I want to make one of the corners of the view round (top-right corner). 我有一个自定义视图,其中包含几层图像,带有文本的布局,图纸等。我想使视图的一个角变为圆角(右上角)。 In other words, I want to crop this corner to make it round - not to set rounded corner background. 换句话说,我想裁剪此角使其变圆-而不是设置圆角背景。

I managed to do it by using clipPath() , but it's running slow since I had to turn the hardware acceleration for this view - so this solution is not suited for me. 我设法通过使用clipPath()做到了这一点,但是它运行缓慢,因为我不得不为此视图打开硬件加速-因此该解决方案不适合我。

Any other way to do that? 还有其他方法吗?

Here is the custom rounded ImageView class extending ImageView. 这是扩展ImageView的自定义圆形ImageView类。 And here variable CORNER_RADIUS is the value of radius. 此处的变量CORNER_RADIUS是radius的值。 Using this code you can create any rounded view just by extending that class from that view. 使用此代码,只需从该视图扩展该类即可创建任何舍入视图。

public class RoundedImage extends android.support.v7.widget.AppCompatImageView
 {
private final static float CORNER_RADIUS = 100.0f;

private Bitmap maskBitmap;
private Paint paint, maskPaint;
private float cornerRadius;

public RoundedImage(Context context) {
    super(context);
    init(context, null, 0);

}

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

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

private void init(Context context, AttributeSet attrs, int defStyle) {
    DisplayMetrics metrics = context.getResources().getDisplayMetrics();
    cornerRadius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, CORNER_RADIUS, metrics);

    paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

    setWillNotDraw(false);
}

@Override
public void draw(Canvas canvas) {
    Bitmap offscreenBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas offscreenCanvas = new Canvas(offscreenBitmap);

    super.draw(offscreenCanvas);

    if (maskBitmap == null) {
        maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
    }

    offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
    canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
}

private Bitmap createMask(int width, int height) {
    Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
    Canvas canvas = new Canvas(mask);

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.WHITE);

    canvas.drawRect(0, 0, width, height, paint);

    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
    canvas.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);

    return mask;
}

} }

How to use is: 使用方法是:

<com.packagename.RoundedImage
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:scaleType="centercrop"
 />

This should not be a problem if you create a transparent canvas for that custom view. 如果您为该自定义视图创建透明画布,这应该不是问题。 Then draw a rounded rectangle on it as a background before the rest of the graphics. 然后在其余图形之前在其上绘制一个圆角矩形作为背景。

The rounded rectangle should be bigger than the canvas and shifted to the left so that the top-right corner of the canvas stays transparent. 圆角矩形应大于画布,并向左移动,以便画布的右上角保持透明。

However is you draw biger images in your custom view and want just to clip that corner than you can just erase that corner with a corner shape Path filled with a paint 但是,您是否在自定义视图中绘制了更大的图像,并且只想剪切该角,而不是仅用角形状擦除该角,就用填充颜料的路径

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM