An invalidate() cascades up, all the way to the root of the tree, and a draw() call comes back down (this is not quite true anymore with Android 3.0 and hardware acceleration though.)
The clip does get scaled, but only at the level where you put scale() call. But the default clipRect() calls creates the intersection of the current clip rect and the new clip rect. You end up clipping with a larger rectangle, but the ancestors have already set a clip rect the size of your invalidated view. On Fri, Jun 17, 2011 at 2:17 AM, Trev16v <[email protected]> wrote: > Thanks Romain. I'm certainly well aware that the problem is my code > and not in ViewGroup, and that one of the individual child Views will > certainly not receive a scaled Canvas if it is invalidated. I think > the reason for my confusion here -- and this will be down to my lack > of knowledge about what goes on behind the scenes between invalidate() > being called and the View's onDraw() subsequently being invoked -- is > that I thought that the invalidation of a child View was somehow > always cascaded down from the ViewGroup. My reason for thinking this > is that, when a child view has invalidate() called, I can see that the > ViewGroups's dispatchDraw() gets invoked first, prior to the child > View's onDraw(). > > Furthermore, when I zoom in, I can see that the parts of the child > Views that are being redrawn on the screen are always being drawn to > the correct scale; it's just as though the clipping isn't being > scaled. This was a further reason why I've perhaps mistakenly thought > that the child View was aways being provided a scaled Canvas from my > ViewGroup to draw on each time it was called to onDraw() following > invalidate() being called on that child. > > Perhaps I'll just have to have my child Views all reference the parent > View's zoom scale factor variable and individually scale themselves, > perhaps having the ViewGroup and child Views all implementing an > Interface that provides methods to delegate down the scale factor. No > big deal in doing that; I was perhaps just trying to be too clever in > my first approach, certainly too ambitious considering my Java / > Android inexperience. > > Thanks, > > Trev > > > > On Jun 17, 2:22 am, Romain Guy <[email protected]> wrote: >> You are scaling the Canvas and not the View itself, the children have >> absolutely no knowledge that you are doing so. When invalidate() is >> invoked on the children, how could they know that you intend to scale >> them? They can't (unless you use Android 3.0+ and the new scale() >> method.) The problem is not in ViewGroup, it's in your code: you need >> to take the scale factor into account when you invalidate the children >> (call invalidate(left, top, right, bottom) on the parent instead.) >> >> >> >> On Thu, Jun 16, 2011 at 6:08 PM, Trev16v <[email protected]> wrote: >> > Hello, >> >> > In my application I need to have a floor plan diagram which can be >> > panned and zoomed. On this diagram are to be a series of small >> > markers. Those little marker Views need to have invalidate() called >> > frequently on them because the graphics drawn to their Canvas is being >> > animated. I have been trying to implement an extended RelativeLayout, >> > which I call ZoomableRelativeLayout, which would enable me to perform >> > simultaneous zooming on all child Views of the ViewGroup. That is, the >> > large floor plan graphic and its markers, all of which are child >> > Views, will simultaneously zoom and pan together. >> >> > In my ZoomableRelativeLayout, I have attempted to perform scaling >> > (zooming) to the Canvas within the overridden dispatchDraw() method, >> > like this: >> >> > protected void dispatchDraw(Canvas canvas){ >> > canvas.save(Canvas.MATRIX_SAVE_FLAG); >> > canvas.scale(mScaleFactor, mScaleFactor); >> > super.dispatchDraw(canvas); >> > canvas.restore(); >> > } >> >> > The mScaleFactor is manipulated by a ScaleListener in the same class. >> >> > It does actually work. I can pinch to zoom the ZoomableRelativeLayout, >> > and all of the views held within properly rescale together. >> >> > Except there's a problem. When the scale is 1, the animated child >> > views are seen to redraw periodically perfectly fine. However, when >> > the scale is other than 1, (e.g. when zooming in), those animated >> > child views are only seen to update in a small clipped portion of >> > their area - or not at all - depending on the zoom scale. >> >> > The problem appears to be that the 'invalid area', or clipping area, >> > for each view seems to remain as if no scaling had been applied to the >> > Canvas in dispatchDraw(). If for example my ZoomableRelativeLayout >> > were to contain a single, simple View that draws a filled rectangle, >> > and it animated by flipping its colour every second via invalidate() >> > and onDraw(), then at a zoom of 1 it'll appear as it should do. >> > However, begin to gradually zoom in, the size of the square expands >> > and moves away from its original position. The only part of the square >> > that animates is whatever part of it still sits underneath that >> > square's original 'area'. >> >> > I have tried looking over the source for ViewGroup to see if I could >> > spot any solution to this problem, and the best thing I could spot was >> > to clear the FLAG_CLIP_CHILDREN via setClipChildren(false). Inspection >> > of the source of ViewGroup seemed to suggest that clipping would no >> > longer be applied, but unfortunately this change has had no visible >> > effect and the problem persists. >> >> > Probably worth mentioning is the fact that whenever I am actually >> > zooming in and out, or when I'm panning the ViewGroup, all of the >> > marker child View graphics *do* periodically redraw properly. So, for >> > example, when I'm panning the floor plan around or zooming, my markers >> > are seen to properly animate. Now when I'm zooming, invalidate() is >> > being called on the ViewGroup itself, obviously; and presumably calls >> > to scrollBy() to perform my panning lead to an invalidate() on the >> > ViewGroup too. It seems that invalidation of the ViewGroup leads to an >> > entire redraw which draws the child views with the clipping bounds >> > scaled as well, so that the child Views' graphics are properly updated >> > on the display. Calling invalidate() on the individual child Views >> > still causes a call to the ViewGroup's dispatchDraw(), but for some >> > reason the clipping area is then 'unscaled'. >> >> > Am I on a bit of a loser with my zoomable ViewGroup strategy? >> >> > Thanks, >> >> > Trev >> >> > -- >> > You received this message because you are subscribed to the Google >> > Groups "Android Developers" group. >> > To post to this group, send email to [email protected] >> > To unsubscribe from this group, send email to >> > [email protected] >> > For more options, visit this group at >> >http://groups.google.com/group/android-developers?hl=en >> >> -- >> Romain Guy >> Android framework engineer >> [email protected] >> >> Note: please don't send private questions to me, as I don't have time >> to provide private support. All such questions should be posted on >> public forums, where I and others can see and answer them > > -- > You received this message because you are subscribed to the Google > Groups "Android Developers" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/android-developers?hl=en > -- Romain Guy Android framework engineer [email protected] Note: please don't send private questions to me, as I don't have time to provide private support. All such questions should be posted on public forums, where I and others can see and answer them -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

