Thursday, June 3, 2010

Animations do not affect layout

Yesterday I wanted to implement a cool transition effect. If you've used an iPhone you've seen things like it scores of times... you push a button and your window smoothly glides from one state (a normal, default, 'viewing' state, say) into a secondary state... perhaps one in which a list which normally only shows 3 items is expanded to show 10 items, pushing less important widgetry out of the way while the user makes their selection. Press the button again and it glides back to the original layout.

Since slick, ultra-smooth animation was what I was after, I made the error of thinking that android.view.animation.* would be just what was needed. I played around with the basic stock Animation types for a while, and just couldn't figure out why, while I could do all sorts of cool things, I couldn't do the one simple thing I wanted : resizing.

Sure, I could trivially send Buttons and TextViews skipping merrily across the screen, fade them out, fade them back in, zoom them in and out, even rotate them by arbitrary angles... so why not resize? And why did they snap back to their original locations when the animation ended?

It was only after looking into the source code for Android's animation package that I realized what was going on... with hindsight it's blindingly obvious, but if you found this article because you're wondering the same thing, allow me set you straight:

Animations only ever affect how a view is displayed. Can't emphasize that enough. It does not affect the view's position or size. That button might look as if it's moving, but that's an illusion... it's real position and size are unchanged. All the animation system does is add a couple of last-minute alterations to how the view is displayed when your window is drawn... the layout is completely unaffected.

That's why views snap back to their original position/zoom/alpha when an animation ends... they never actually changed in the first place. Similarly, that's why there's no ResizeAnimation type in the package... if you can't touch layout at all, resizing is impossible.

IMHO layout animations are a missing part of the SDK. Perhaps some day it'll be addressed, but for now you have to roll your own. It's not that hard to do, and I hope to demonstrate how - using those lovely Interpolator types for extra gorgeousness - in a follow-up article.