Can I draw outside the bounds of an Android Canvas
Asked Answered
A

6

39

I'm porting an app written in a graphics environment that allows drawing to happen outside the bounds of the clipping rectangle. Any way to do this in Android?

Atmospherics answered 26/10, 2010 at 21:42 Comment(0)
P
55

try to set

android:clipChildren="false" 

to the parent view

Prophylactic answered 21/11, 2013 at 10:38 Comment(0)
P
48

To draw outside the bounds, you need to expand the clipRect of the canvas.

Check out the overloaded clipRect methods on the Canvas class.

Note - You will need to specify the Region operation because the default operation is INTERSECT. So something like this:

Rect newRect = canvas.getClipBounds();
newRect.inset(-5, -5)  //make the rect larger

canvas.clipRect (newRect, Region.Op.REPLACE);
//happily draw outside the bound now
Puzzle answered 19/3, 2013 at 17:21 Comment(5)
It doesn't work at all. I just resize canvas with (-2000, -2000) parameters, then translate it but the image I draw is still clipped.Alanna
but if you do that on every onDraw(Canvas canvas) then aren't you making the computer do a lot of extra work ?Inerrant
@SomeoneSomewhere i am not sure what the effect on performance is when you change clip rects (esp. with HA on vs software rendering). but this should be simple to measure through profiling.Puzzle
This works the first time Invalidate is called. Subsequent calls do not work.Yacano
Region.Op.REPLACE got deprecated at API >= 26 Do you have another solution? Im running out all SOF and didnt found yetOsmo
P
10

You can draw where you like, but nothing will be saved outside the clipping rectangle.

Preparator answered 26/10, 2010 at 22:46 Comment(0)
G
5

The answer @numan gave is almost ok, the problem is memory allocation with that approach, so we should be doing this, instead:

// in constructor/elsewhere
Rect newRect = new Rect();

// in onDraw
canvas.getClipBounds(newRect);
newRect.inset(0, -20);  //make the rect larger
canvas.clipRect(newRect, Region.Op.REPLACE);

That solves the problem :-)

Gallantry answered 16/10, 2016 at 17:4 Comment(3)
How to init newRect ?Kennakennan
Ok, I guess the point here that newRect is allocated once per object init, instead of allocating it each time onDraw is called.Kennakennan
Region.Op.REPLACE is deprecated. It doesn't work anymore!Rexer
A
3

If you want to draw text out of bounds in TextView, you should be doing this instead:

<TextView
    ...
    android:shadowColor="#01000000"
    android:shadowDx="100" // out of right bound
    android:shadowDy="0"
    android:shadowRadius="1"
.../>

It's not working to use clipRect() like @numan's answer because TextView clip it's own rect in onDraw():

if (mShadowRadius != 0) {
    clipLeft += Math.min(0, mShadowDx - mShadowRadius);
    clipRight += Math.max(0, mShadowDx + mShadowRadius);

    clipTop += Math.min(0, mShadowDy - mShadowRadius);
    clipBottom += Math.max(0, mShadowDy + mShadowRadius);
}

canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom);

Last but not least, Don't forget to set android:clipChildren="false" and android:clipToPadding="false" in your parent ViewGroup

Avidin answered 14/11, 2017 at 9:38 Comment(1)
[SOLVED] WOKED! ((ViewGroup) parent).setClipChildren(true); ((ViewGroup) parent).setClipToPadding(true); solved for my using this when I needed to draw over the other views at same hierarchy thx !Osmo
T
2

If what you want is just draw outside the view bounds (programmatically), cut the long story short.

parentLayout.setClipChildren(false);

or via xml :

 android:clipChildren="false"

enter image description here

Tracietracing answered 31/12, 2021 at 14:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.