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?
6 Answers
try to set
android:clipChildren="false"
to the parent view
- 919
- 9
- 11
-
3I don't know about the question but i wanna thank you for solving, my problem, which i was facing. Thank you. This is what i was looking for. – shadyinside Apr 06 '14 at 17:42
-
Please take a look at http://stackoverflow.com/questions/32735119/draw-outside-the-bounds-of-an-android-canvas – Morteza Rastgoo Sep 23 '15 at 10:24
-
@MortezaRastgoo the linked question (and answers) do not directly translate to this problem at all. – Martin Marconcini Aug 22 '16 at 21:41
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
- 5,233
- 2
- 43
- 58
- 19,196
- 9
- 60
- 66
-
2It doesn't work at all. I just resize canvas with (-2000, -2000) parameters, then translate it but the image I draw is still clipped. – tomrozb Sep 27 '13 at 07:58
-
but if you do that on every `onDraw(Canvas canvas)` then aren't you making the computer do a lot of extra work ? – Someone Somewhere Jan 06 '14 at 04:42
-
@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. – numan salati Jan 07 '14 at 18:19
-
This works the first time Invalidate is called. Subsequent calls do not work. – jjxtra Sep 01 '15 at 19:38
-
This works but i want the view to be on top of the parent tab bar.how can i do that? – Morteza Rastgoo Sep 22 '15 at 12:53
-
Please take a look at http://stackoverflow.com/questions/32735119/draw-outside-the-bounds-of-an-android-canvas – Morteza Rastgoo Sep 23 '15 at 09:43
-
1@MortezaRastgoo the linked question (and answers) do not directly translate to this problem at all. – Martin Marconcini Aug 22 '16 at 21:41
-
5Region.Op.REPLACE got deprecated at API >= 26 Do you have another solution? Im running out all SOF and didnt found yet – Arthur Melo Feb 28 '19 at 22:01
You can draw where you like, but nothing will be saved outside the clipping rectangle.
- 24,495
- 12
- 73
- 109
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 :-)
-
-
2Ok, I guess the point here that newRect is allocated once per object init, instead of allocating it each time onDraw is called. – Anton Malmygin May 05 '17 at 12:19
-
1
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
- 711
- 7
- 10
-
[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 ! – Arthur Melo Feb 28 '19 at 22:07
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"
- 3,221
- 4
- 32
- 42