Draw Rectagle with fill outside bounds

老子叫甜甜 提交于 2019-12-06 15:03:36
Ted Hopp

I'm still not entirely sure what you're trying to accomplish. The shape you show can be drawn as follows:

// set up some constants
int w = canvas.getWidth();
int h = canvas.getHeight();
RectF rect = new RectF(100, 100, w - 100, h - 100);
float radius = 10.0f; // should be retrieved from resources and defined as dp
float borderWidth = 2.0f; // ditto
int innerRectFillColor = 0x33000000; // or whatever shade it should be

// first fill the interior
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(innerRectFillColor);
paint.setStyle(Paint.Style.FILL);
canvas.drawRoundRect(rect, radius, radius, paint);
// then draw the border
paint.setColor(Color.WHITE);
paint.setStrokeWidth(borderWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRoundRect(rect, radius, radius, paint);

If instead you want to draw around a hole (so the background shows through), the trick of drawing the surrounding rectangles won't work because of the rounded corners (the border also makes it more complicated). Instead, you can create a separate Bitmap that has a transparent hole and then draw that. You'll need to use a Porter-Duff transfer mode of CLEAR to punch the hole in the bitmap:

// same constants as above except innerRectFillColor is not used. Instead:
int outerFillColor = 0x77000000;

// first create an off-screen bitmap and its canvas
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas auxCanvas = new Canvas(bitmap);

// then fill the bitmap with the desired outside color
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(outerFillColor);
paint.setStyle(Paint.Style.FILL);
auxCanvas.drawPaint(paint);

// then punch a transparent hole in the shape of the rect
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
auxCanvas.drawRoundRect(rect, radius, radius, paint);

// then draw the white rect border (being sure to get rid of the xfer mode!)
paint.setXfermode(null);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
auxCanvas.drawRoundRect(rect, radius, radius, paint);

// finally, draw the whole thing to the original canvas
canvas.drawBitmap(bitmap, 0, 0, paint);

Here's how I punched out a rounded rectangle window from my background. You're actually drawing four rectangles around a center window, then filling that window with a RoundRectShape that has an outer radius of 0 and thin inset with rounded edges.

    Rect frame = new Rect(left, top, right, bottom); // Window location on screen
    int width = canvas.getWidth();
    int height = canvas.getHeight();


    paint.setColor(maskColor); // Make sure your mask is semi-transparent

    // Draw four bounding rectangles  
    canvas.drawRect(0, 0, width, frame.top, paint); 
    canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint);  
    canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint);
    canvas.drawRect(0, frame.bottom + 1, width, height, paint);

    // Create rounded rectangle to fill window 
    float outerRadii[] = {0, 0, 0, 0, 0, 0, 0, 0}; // The outside edge is just a rectangle
    float innerRadii[] = {8, 8, 8, 8, 8, 8, 8, 8}; // The inside edge is rounded
    RoundRectShape roundRect = new RoundRectShape(outerRadii, new RectF(5,5,5,5), innerRadii); // We'll stick this shape into the frame we made

    roundRect.resize(frame.width()+1, frame.height()+1); // Adjust size to match the punched-out frame 
    canvas.save();
    canvas.translate(frame.left, frame.top); // The RoundRectShape draws to the canvas at (0,0), so we need to offset the canvas, draw, then restore
    roundRect.draw(canvas, paint);
    canvas.restore();

And here's the result:

http://i.stack.imgur.com/4qdTw.png

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!