PhoneGap on WP7 tip #1: Handling Orientation

 

Today’s PhoneGap on Windows Phone 7 tip involves handling orientation changes. This means when a user rotates their phone from portrait to landscape, the content should rotate as well. Not only that, in some scenarios elements on the screen should reformat for readability and ease of interaction.

As I mentioned in the introductory post,, you can do a lot of things within your application just working with HTML/JS/CSS inside the PhoneGap control. But you’ll gain a whole new set of app superpowers if you step outside of that. We’re starting today with something small – how to have the PhoneGap part of application rotate properly as the phone changes orientation.

To get ready for today’s tip, let’s create a new project in Visual Studio using the PhoneGap template that’s described in the introduction to the tip series.

image

It’s sneaky because you need to click on the Visual C# section on the left pane of the window to display the entire list of templates.

Once you create the project, what you’ll have is essentially a Silverlight for Windows Phone project. PhoneGap is running in a host Silverlight XAML page. By default, Silverlight for Windows Phone applications do not run in landscape mode. You can observe this by running the application (press F5) and click one of the screen rotation buttons on the phone emulator.

image

You’ll see that the emulator rotates, but the text does not.

image

This is a characteristic of the host Silverlight application as well as the HTML rendering inside of the PhoneGap control.

Allowing the host application to support landscape mode is pretty easy. In Solution Explorer, double click on the MainPage.xaml file. In the Properties window, find the SupportedOrientations and change it to PortraitOrLandscape. Note that you can do this directly in the XAML if you are feeling adventurous. Also note that there is an Orientation property which controls the starting orientation, so if you want your app to launch in landscape orientation, this is how you would control that.

image

Run the app again and rotate the emulator.

image

Success! We now have the host page and the PhoneGap control rotating.

At this point you could also put JS code in to respond when the devices is rotated, to adjust the UI via swapping out divs or using CSS to control it. Here’s a simple example, based on the boilerplate index.html page included in the template.

  1: <!DOCTYPE html>
  2: <html>
  3:   <head>
  4:     <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" />
  5:     <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
  6:     
  7:     <title>PhoneGap WP7</title>
  8:     
  9:       <link rel="stylesheet" href="master.css" type="text/css" media="screen" title="no title" charset="utf-8"/>
  10:       
  11:       <script type="text/javascript">
  1:  
  2:           // provide our own console if it does not exist, huge dev aid!
  3:           if(typeof window.console == "undefined")
  4:           {
  5:           window.console = {log:function(str){window.external.Notify(str);}};
  6:           }
  7:         
  8:           // output any errors to console log, created above.
  9:           window.onerror=function(e)
  10:           {
  11:               console.log("window.onerror ::" + JSON.stringify(e));
  12:           };
  13:         
  14:           console.log("Installed console ! ");
  15:       
 </script>
  1:  
  2:       
  3:       <script type="text/javascript" charset="utf-8" src="phonegap-1.2.0.js">
  1: </script>
  2:        
  3:       <script type="text/javascript">
  4:  
  5:         document.addEventListener("deviceready",onDeviceReady,false);
  6:  
  7:         // once the device ready event fires, you can safely do your thing! -jm
  8:         function onDeviceReady()
  9:         {
  10:             document.getElementById("welcomeMsg").innerHTML += "PhoneGap is ready! version=" + window.device.phonegap;
  11:             window.addEventListener("orientationchange", orientationChange, true);
  12:             
  13:         }
  14:         function orientationChange(e) {
  15:             var orientation = "portrait";
  16:             if (window.orientation == -90 || window.orientation == 90) orientation = "landscape";
  17:             document.getElementById("orientation").innerHTML = orientation;
  18:         }
  19:       
 </script>
  12:       
  13:      
  14:       
  15:  
  16:   </head>
  17:   <body>
  18:     <h1>Hello PhoneGap</h1>
  19:     <div id="welcomeMsg"></div>
  20:     <div id="orientation">portrait</div>
  21:   </body>
  22: </html>

Note the new DIV to hold the text identifying the current orientation state, and the orientationChange function wired up to the event in the onDeviceReady function. It’s the host page rotation that causes this event to fire inside the PhoneGap user control. Without the property to allow both orientations, this event would never fire.

If you want to handle the orientation changed outside the PhoneGap part of your app, you can wire up a C# event handler at the page level as well. To do this, return to the properties windows for MainPage.xaml and switch to Events at the top of the window. Find the OrientationChanged event. We’ll create an event handler by double clicking on the event name.

image

The MainPage.xaml.cs window will open, ready for us to type in our code.

image

Allowing the user to work with the application in both portrait and landscape layout makes it more flexible. In later articles I will cover how there are even aspects of Windows Phone development that respond automatically to the orientation changing.

Let me know your feedback in the comments, and look for many more PhoneGap on Windows Phone tips coming in subsequent weeks, in increasing levels of complexity. :)