8

I want to fill the area outside a rectangle on a canvas. I use

 canvas.drawRect(pTopLeft.x, pTopLeft.y, pBotRight.x, pBotRight.y, paint);

to draw the rectangle, but can't figure out how to fill outside the rectangle/clip.

Thanks Geoff

Geoff
  • 338
  • 3
  • 8

4 Answers4

19

Thanks ted and trojanfoe - the neatest solution I've come up with is

    Point pTopLeft = new Point();
    Point pBotRight = new Point();

    //TODO:set x,y for points

    Rect rHole = new Rect(pTopLeft.x, pTopLeft.y, pBotRight.x, pBotRight.y);
    //assume current clip is full canvas
    //put a hole in the current clip
    canvas.clipRect(rHole,  Region.Op.DIFFERENCE);
    //fill with semi-transparent red
    canvas.drawARGB(50, 255, 0, 0);
    //restore full canvas clip for any subsequent operations
    canvas.clipRect(new Rect(0, 0, canvas.getWidth(), canvas.getHeight())
                    , Region.Op.REPLACE);
Geoff
  • 338
  • 3
  • 8
7

You aren't going to fill outside the clip; that's the kind of thing clip is there to prevent! If you want to fill the space outside a rect and inside the drawing layer bounds, construct four auxiliary rects:

Rect above = new Rect(0, 0, canvas.getWidth(), pTopLeft.y);
Rect left = new Rect(0, pTopLeft.y, pTopLeft.x, pBotRight.y);
Rect right = new Rect(pBotRight.x, pTopLeft.y, canvas.getWidth(), pBotRight.y);
Rect bottom = new Rect(0, pBotRight.y, canvas.getWidth(), canvas.getHeight());

Then fill these.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • Thanks Ted. I played around with filling the whole canvas then trying to make the clip region transparent - no good. Your method did the trick. – Geoff Feb 17 '11 at 20:03
  • 5
    I know you have it working now, but one other possibility occurred to me: set a clip region that excludes the middle and fill. I think that if you use `canvas.clipRect(innerRect, Region.Op.DIFFERENCE)` it will punch the hole you want. – Ted Hopp Feb 18 '11 at 03:34
  • @TedHopp Actually i cant get any rectangles. Can u share me how to draw rectangle and fill rectangle outside bounds? – ImMathan Sep 05 '14 at 05:22
  • @ImMathan - Please post a separate question explaining what you are trying to do, what you have tried, and what about it isn't working. Without knowing that, it's hard to know how to help. – Ted Hopp Sep 05 '14 at 05:25
  • @TedHopp here is my question. http://stackoverflow.com/questions/25679259/draw-rectagle-with-fill-outside-bounds – ImMathan Sep 05 '14 at 05:40
2

ICS and above ...

canvas.clipRect(rHole,  Region.Op.DIFFERENCE);

XOR, Difference and ReverseDifference clip modes are ignored by ICS if hardware acceleration is enabled.

Just disable 2D hardware acceleration in your view:

myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Reference Android: Howto use clipRect in API15

Community
  • 1
  • 1
SHS
  • 1,414
  • 4
  • 26
  • 43
0

You can't draw outside of the Canvas; that area belongs to the parent View. Do you have the ability to subclass the parent View and do your drawing in that class instead?

If you want to draw outside of the Canvas clip then you'll have to invalidate() the areas you are interested in.

trojanfoe
  • 120,358
  • 21
  • 212
  • 242