How to make a view with rounded corners?

前端 未结 20 1278
遇见更好的自我
遇见更好的自我 2020-11-27 11:08

I am trying to make a view in android with rounded edges. The solution I found so far is to define a shape with rounded corners and use it as the background of that view.

20条回答
  •  执念已碎
    2020-11-27 11:36

    Another approach is to make a custom layout class like the one below. This layout first draws its contents to an offscreen bitmap, masks the offscreen bitmap with a rounded rect and then draws the offscreen bitmap on the actual canvas.

    I tried it and it seems to work (at least for my simple testcase). It will of course affect performance compared to a regular layout.

    package com.example;
    
    import android.content.Context;
    import android.graphics.*;
    import android.util.AttributeSet;
    import android.util.DisplayMetrics;
    import android.util.TypedValue;
    import android.widget.FrameLayout;
    
    public class RoundedCornerLayout extends FrameLayout {
        private final static float CORNER_RADIUS = 40.0f;
    
        private Bitmap maskBitmap;
        private Paint paint, maskPaint;
        private float cornerRadius;
    
        public RoundedCornerLayout(Context context) {
            super(context);
            init(context, null, 0);
        }
    
        public RoundedCornerLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context, attrs, 0);
        }
    
        public RoundedCornerLayout(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;
        }
    }
    

    Use this like a normal layout:

    
    
        
    
        
    
    
    

提交回复
热议问题