The blog of dlaa.me

Spin Spin Sugar [Updated code to easily animate orientation changes for any Windows Phone application]

A few weeks after the initial release of the Windows Phone Developer Tools in April, I blogged a sample showing how to easily animate device orientation changes for Windows Phone 7 applications. I noted at the time that the default behavior for application projects is no animation - the app immediately switches to the new orientation when the device is rotated (click here for a brief video of the default behavior). While this is clearly the simplest approach, I wanted to enable something a little fancier by smoothly animating the application's rotation from one orientation to another - just like the built-in applications do.

To show what I'm talking about, here's a video of my implementation running on the emulator:

Video of animated orientation change behavior

FYI: The buttons in the video rotate the device one quarter turn clockwise or counter-clockwise. I begin by rotating counter-clockwise once, then clockwise once back to the starting orientation, then clockwise three more times to loop all the way around. And then show off just a bit. :)

Note: I made that video back in April; the emulator looks a little different now, but the animation works just the same.

 

As of yesterday's release of the Windows Phone Developer Tools Beta, some of the platform changes have invalidated my original implementation. But that's okay, because I've updated the code to work with the latest release - and made a few improvements along the way! :)

 

[Click here to download the AnimateOrientationChanges sample for Windows Phone 7.]

 

Notes:

  • [Please review the "Notes" section of my previous blog post for additional information.]
  • The implementation is now based off PhoneApplicationFrame which simplifies things a bit by avoiding the need to track state across pages. Conveniently, this also makes the setup process a bit easier. What's more, I was able to get rid of the TranslateTransform based on a suggestion by Seema Ramchandani, one of the Silverlight performance experts. And I've added a bit of code to avoid unnecessary calls to InvalidateArrange which helps free up a few extra CPU cycles.
  • One of my earlier concerns was that I hadn't been able to run code on actual Windows Phone hardware, so I wasn't sure the snappy performance I saw under the emulator carried over to the device. Fortunately, I've gotten access to an actual prototype and have verified the sample application runs quite smoothly in the real world, thank you very much. :)
  • That said, my sample is pretty simple - Seema expressed concern about possible slowness for the more complex layouts real applications might use. And while I share her concerns, the options for improving the situation in such cases all seem like they'll degrade the visual quality of the rotation animation. The current implementation gives the best quality it can on any device for any layout (and automatically degrades as necessary to catch up if it falls behind); the alternatives create animations that just won't be as smooth. :( So I'm reluctant to start down that path until I know it's necessary. Please let me know what your experience is - whether good or bad - so I can make an informed decision!
  • Here are the complete directions for adding rotation animation to a new application (if you're upgrading an existing application, please undo all the previous install steps first!):
    1. Enable support for orientation changes by making the following change to the XAML for the relevant PhoneApplicationPages (note that rotation is no longer enabled by default for new pages):
      SupportedOrientations="Portrait"
      SupportedOrientations="PortraitOrLandscape"
    2. Verify (by running in the emulator) the pages you expect to support rotation really do - if things aren't rotating at this point, trying to animate the rotations won't help. :)
    3. Add the AnimateOrientationChangesFrame.cs code file from the sample to your project/solution.
    4. Open App.xaml.cs and change the RootFrame initialization in the InitializePhoneApplication method (you may need to expand the Phone application initialization region at the bottom):
      RootFrame = new PhoneApplicationFrame();
      RootFrame = new Delay.AnimateOrientationChangesFrame();
    5. Done; rotations will now be animated! To customize the animation, use the Duration, EasingFunction, and IsAnimationEnabled properties which are all still present and continue to work as outlined in the previous post.
  • The phone emulator has an annoying bug where it frequently fails to notify applications about an orientation change that just happened. This problem has nothing to do with my code (you can reproduce it by enabling rotation for any application), but shows up regularly when playing around with the sample app in the emulator. When the orientation gets "stuck" like that, just rotate a few more times and things sort themselves out. (Fortunately, this problem does not exist on actual phone hardware!)
  • The PageOrientation.PortraitDown value remains unsupported with this release because the platform still does not support it.

 

On the one hand, animating orientation changes is kind of a whimsical behavior to add to an application - but on the other hand, it helps to create the kind of pleasing, platform-consistent experience that users appreciate and enjoy. AnimateOrientationChangesFrame isn't going to turn a crummy application into a good one - but it just might add some polish to help turn a good application into a great one.

I've had fun creating this sample - I hope you enjoy using it!