Friday, July 26, 2013

DevBytes: Anticipation & Overshoot, Part 2

Like my previous DevBytes episode, Anticipation and Overshoot, Part I," this episode covers cartoon animation techniques for making UI elements more engaging and playful. The code in this episode shows how to change and animate how a button is drawn to make it seem more alive and organic.

This and other cartoon animation techniques were discussed in the talk A Moving Experience at Google I/O 2013.


YouTube: DevBytes: Anticipation and Overshoot - Part 2

Thursday, July 25, 2013

New in Android 4.3: ViewOverlay

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.

Android devs
Come out to play:
Use the new

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!

Friday, July 19, 2013

DevBytes: Anticipation and Overshoot, Part 1

Some principles of cartoon animation can be used to provide more engaging and more interactive experiences in applications.

This episode demonstrates principles of anticipation and overshoot with a simple button click, showing how to animate changes in the button's appearance to make it interact more playfully with the user.

This and other cartoon animation techniques were discussed in the talk A Moving Experience at Google I/O 2013



Friday, July 12, 2013

DevBytes: Curved Motion

This is a demo that +Romain Guy and I showed in our A Moving Experience talk at Google I/O this year, showing how to use the existing TypeEvaluator and Animator APIs to get curved motion for your animations.

In the real world, things don't move in straight lines. Moving items around on the screen should feel as natural as possible; sometimes curved motion can help.

This episode shows how to use the existing animation APIs to get easy curved motion for your UIs.

The helper classes come from an article I posted on my blog last year: