XBoxReveal HTML5 Windows Phone Sample: Multiple Resolutions

In a previous article I wrote about writing an XBox Reveal Count Down Timer for Windows Phone using HTML5 & CSS. By the end of the article we ended up with the following

finalImage

During testing for the sample, I was testing on the Windows Phone Emulator running at 720p running at 720×1280 and everything looks fine.  The challenge is, Windows Phone comes in multiple resolutions so running it on WVGA which is 480×800 you get the following output

wxga-xboxreveal

If you catch it, you will notice the alignment of the image is a little off and is too far down. The next few steps will go through a couple of ways to fix that.

Optimizing Images

Windows Phone 8 comes with multiple resolutions and MSDN’s article Multi-resolution apps For Windows Phone 8 is a great reference and recommended read.

A couple of methods that can be used which are

  1. Javascript code to set the appropriate image depending on the size
  2. Using ScriptNotify and InvokeScript to communicate between C# & JavaScript

In our example, we are going to use option #2 as it will allow me to show how to communicate between C# and Javascript. I do have a previous article on ScriptNotify and InvokeScript on Windows Phone but this is a pretty good time to update that sample as it was written in 2010.

The MSDN article Multi-resolution apps For Windows Phone 8 has a great little helper class called ResolutionHelper which helps determine the current resolution your app is running in. Add the following class to MainPage.xaml.cs outside of the MainPage partial class (NOTE: you can add a new class file and will leave that to you to decide)

public enum Resolutions { WVGA, WXGA, HD720p };

public static class ResolutionHelper
{
    private static bool IsWvga
    {
        get
        {
            return App.Current.Host.Content.ScaleFactor == 100;
        }
    }

    private static bool IsWxga
    {
        get
        {
            return App.Current.Host.Content.ScaleFactor == 160;
        }
    }

    private static bool Is720p
    {
        get
        {
            return App.Current.Host.Content.ScaleFactor == 150;
        }
    }

    public static Resolutions CurrentResolution
    {
        get
        {
            if (IsWvga) return Resolutions.WVGA;
            else if (IsWxga) return Resolutions.WXGA;
            else if (Is720p) return Resolutions.HD720p;
            else throw new InvalidOperationException("Unknown resolution");
        }
    }
}

In the MainPage.Browser_Loaded() method, add the following code to the end

Browser.LoadCompleted += (s, args) =>
{
    // setup the image to display
    var img = "";
    var height = "800px";
    switch (ResolutionHelper.CurrentResolution)
    {
        case Resolutions.HD720p:
            img = "images/bg-720p.png";

            break;
        case Resolutions.WXGA:
            img = "images/bg-wxga.png";
            height = "800px";
            break;
        case Resolutions.WVGA:
            height = "800px";
            img = "images/bg-wvga.png";
            break;
        default:
            throw new InvalidOperationException("Unknown resolution type");
    }
    Browser.InvokeScript("setImage", new string[] { img, height });
};

Notice how at the end of the code, Browser.InvokeScript is called passing in the image to set. Because of this we need to update our JavaScript.  Open up Html/js/index.js and add the following code which will essentially set the image passed in from C#

function setImage(img, height) {
    var elem = document.getElementById('bg');
    if (elem) {
        elem.style.height = height;
        elem.src = img;
    }
}

We also need to change our phone.css to the following by removing

@media all and (orientation:portrait) {
    @-ms-viewport {
        width:320px;
        user-zoom: fixed;
        max-zoom: 1;
        min-zoom: 1;
    }
}

@media all and (orientation:landscape) {
    @-ms-viewport {
        width:480px;
        user-zoom: fixed;
        max-zoom: 1;
        min-zoom: 1;
    }
}

and adding

@-ms-viewport {
    width:480px;
        user-zoom: fixed;
        max-zoom: 1;
        min-zoom: 1;
}

Before this will work, you will need to add some images to be loaded. Download the following images and add them to /Html/images/ directory.

  1. WVGA
  2. WXGA
  3. 720p 

Run the app on the different emulators and the right sizes should be loaded but now our alignment is way off.

Fixing Alignment

Next thing we will do is fix the alignment for the count down timer and the Multi-resolution apps For Windows Phone 8 article on MSDN will help. Windows Phone comes in three resolutions

  1. WVGA with a resolution of 480×800
  2. WXGA with a resolution of 769×1280
  3. 720p with a resolution of 720×1280

To fix our alignment issues we will be updating the timer.css file using CSS3 Media Queries which has been supported in IE since version 9 and Windows Phone 8 has the IE10 browser.

Add the following CSS to the end of the timer.css file

/* WVGA Support */
@media screen and (min-device-width : 480px) and (max-device-width : 480px){
    #table {
        margin-top:300px;
           width: 550px
    }
    .numbers {
        font-size: 52px;
    }
    .title {
        font-size: 20px;
    }

}

/* WXGA Support */
@media screen and (min-device-width : 768px) and (max-device-width : 768px){
    #table {
        margin-top:300px;
          width: 550px
    }
    .numbers {
        font-size: 52px;
    }
    .title {
        font-size: 20px;
    }
}

/* 720p Support */
@media screen and (min-device-width : 720px) and (max-device-width : 720px){
    #table {
        margin-top:320px;
        width: 550px
    }
    .numbers {
        font-size: 52px;
    }
    .title {
        font-size: 20px;
    }
}

NOTE: I purposely split the CSS for all screen sizes so readers can see how to split things up. Ideally if things are common, as the font sizes are, you want to update it from one spot only.

Now if you run the app in all three emulators, you will see the alignment issue fixed on the screen.

allEmus

Till this point when you use the app you would have noticed that you can scroll the page with your finger vertically and horizontally which is not the best experience.  In the next part of this series we’ll look at fixing that issue and getting the app ready for the store for submission.


Warning: count(): Parameter must be an array or an object that implements Countable in /home/usnbis1maldq/domains/markarteaga.com/html/wp-includes/class-wp-comment-query.php on line 405