Since we just released Android 4.3 yesterday, I thought I’d wax poetic about one of the features I worked on in the release: Overlays.
There are many ways to get custom graphics (drawables) to appear in a view. You can set a background drawable if that’s what you want, or you can use an ImageView, or you can create a custom View subclass and override onDraw(). Or if you want to draw them over the children in a layout, you can override the layout and override dispatchDraw() to draw them after all of the children (after a call to super.dispatchDraw()). But sometimes you just want something simpler: ViewOverlay.
Here’s how it works:
You call View.getOverlay(), which returns a ViewOverlay object. Then you call add(Drawable) on that overlay object… and that’s it. You can also call remove(Drawable) to get rid of the drawable or clear() to get rid of everything in the overlay, but that’s the entire API. The only other detail is that you need to set the bounds on your drawables (as you would if you were drawing them manually in onDraw()); the overlay doesn’t do any positioning or sizing, it simply draws everything you tell it to, in the order in which the objects are added.
Oh, and one other thing: you can also add View objects to an overlay if you get that overlay from a ViewGroup. That is, ViewGroup overrides getOverlay() to return a ViewGroupOverlay, which is a subclass of ViewOverlay that also deals with views in addition to drawables. Once again, the API is simple: there’s an add(View) method and a remove(View) method. And once again, you are responsible for positioning/sizing the views where you want them in the overlay; the overlay does not do any layout.
Essentially, the overlay is a container for drawables (and sometimes views) that is the exact size of its host view. It doesn’t do layout; it just draws the stuff its told to, after it’s drawn everything else in its host view (including any children of that host view, if the view is a ViewGroup).
Important caveat, especially with respect to ViewGroupOverlay: The overlay is intended for temporary display of views, not for any long-term or functional use for views. In particular, the views there are not laid out by the container (as noted above) and do not participate in focus or input events. Overlays were created to be a visual-only mechanism, for things like transient animations. Think about things like fading out a view. This can be tricky in some situations where removing it immediately removes it from the view hierarchy and makes it tough to have it drawn while it’s fading out. Now you can pop it into the overlay of its parent while it’s going away.
Here’s another interesting thing to ponder: you can add drawables/graphics anywhere in the view hierarchy that makes sense for your situation. So, for example, if you wanted to fade out a view or some drawable while sliding it off the screen, or up-scaling it, outside of its parent container, this might normally be a problem because parent containers like to clip their children to their bounds by default. Now you can add the object into an overlay anywhere up the tree, to give you the flexibility to move/resize it as you see fit without worrying about the clipping constraints of that original parent.
Anyway, I’m sure you can find interesting things to do with overlays. So go ahead!