SplashScreenImage_thumb[1]First impressions in Windows Phone 7 (WP7) applications are just as important as they are in real life. You only get the opportunity to make a first impression once, so make it a good one. In the case of WP7 applications, the first impression a user will get is from the splash screen. If you haven’t taken the effort to customize your splash screen, then user’s will immediately think that you haven’t taken much effort with the rest of your application.

Requirements

According to section 5.2.1 of the Windows Phone 7 Application Certification Requirements:

a. The application must render the first screen within 5 seconds after launch.
The application may provide a splash screen image in a file called SplashScreenImage.jpg in the root of the XAP package while the application is still trying to load. However, the first application screen must be rendered within the 5 second requirement even when there is a splash screen.
Microsoft recommends that the application provides a splash screen image only when it takes longer than 1 second to load the first screen.

b. Within 20 seconds after launch, the application must be responsive to user input.

Do I Need a Splash Screen Then?

You actually only need a splash screen if your application takes more than one second to load, and in fact you can dramatically increase the start-up time of your application by removing the splash screen. If your application is taking more than one second, then make sure that your splash screen gives a good impression and is visually appealing.

SplashScreenImage_thumb[3]SplashScreenImage_thumb[5]

Slow to Start Applications

If your application takes longer than 5 seconds to load and show it’s first page, then you will fail certification, so what can you do?

Prevention is Better than Cure

Well, firstly try to delay the loading of large resources and processing data until after your first page has loaded. This means avoiding doing any processing in page or view model constructors. If you wait until the page has already been navigated to, by overriding the OnNavigatedTo method, then you know that the page has been loaded.

public class PageViewModel 
{
    public IsDataLoaded { get; set; }
    public void LoadData() 
    { 
        if (!this.IsDataLoaded) 
        {
            // Do what you need to do to load data.
            this.IsDataLoaded = true;
        }
    }
}

public partial class MainPage : PhoneApplicationPage 
{
    public MainPage() 
    {
        this.ViewModel = new PageViewModel();
        InitializeComponent();
    }

    private PageViewModel ViewModel 
    {
        get { return this.DataContext as PageViewModel; }
        set { this.DataContext = value; }
    }

    protected override OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
        this.ViewModel.LoadData();
    }
} 


Showing a Splash Screen for Longer than 5 Seconds

If you need to show a splash screen for longer, then you might be tempted to create a separate page (SplashScreen.xaml for example), and then navigate to this page as your first page, display the same splash screen image on it while you do your loading, then navigate to your main page. However, don’t be tempted; this will introduce more problems with it solves as the page will exist in the page stack and when the user backs out of your application they’ll go through your splash screen, which will feel awkward at best.

A better approach would be to implement a an overlay on your main page that is shown by default, and then hidden when the loading has finished. One option for your overlay is to use the SplashScreenImage.jpg in an Image control, so that the transition to the first page is seamless to the user. You then use the OnNavigatedTo override for your page to kick off your resource loading, data handling, etc. that is taking a long time to load, and once it’s complete you can then hide the overlay.

So, the XAML for your page would look like something like this:

<phone:PhoneApplicationPage 
    x:Class="DerekLakin.WP7Trenches.Splash.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
    shell:SystemTray.IsVisible="False">
    <Grid x:Name="LayoutRoot">
        // Your normal page content goes here.

        <Image x:Name="_overlay" Source="/SplashScreenImage.jpg" />
    </Grid>
</phone:PhoneApplicationPage>

Landscape Orientation

NOTE: You really should consider adding full support for the landscape orientation,especially for pages that accept text input because some devices have a hardware keyboard that is landscape oriented. You will alienate your users very quickly if you force them to enter text sideways!

Setting shell:SystemTray.IsVisible="False" will ensure that your page is full screen, so the user will not see any visual difference between the loaded splash screen and your splash overlay. You also need to ensure that the Orientation is set to Portrait because WP7 always shows splash screens in this orientation. Also, don’t worry if the designer doesn’t show the splash image and shows the "blue squiggly" for the Source property on the image; trust me it works! Once you’ve loaded your data and you hide your overlay, you can enable the system tray and landscape orientation if necessary.

The code-behind in your main page will look something like this:

using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;

namespace DerekLakin.WP7Trenches.Splash
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        protected override OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigated(e);

            // Start your data loading here. A BackgroundWorker
            // might be useful for this.
            // When it's done, call the LoadComplete method.
        }

        private void LoadComplete()
        {
            this._overlay.Visibility = Visibility.Collapsed;
            this.SupportedOrientations = 
                SupportedPageOrientation.PortraitOrLandscape;

            // Uncomment the following line if you want the system tray.
            // SystemTray.IsVisible = true;
        }
    }
}



Kicking it Up a Notch

Toolkit Reference

NOTE: If you have installed the Silverlight Toolkit you may find that adding a reference in your WP7 project results in a reference to this location even if you’ve actually added the library from a different location. I get this all the time because I download and build the latest from Codeplex in a different location. To fix this, just copy the assembly to a location within your solution hierarchy and add a <HintPath /> element to the assembly reference in the XML for the .csproj file. The value is a relative path from the project folder.

If you really want to engage the user while your application loads, and to show them that your application is still doing something, you could add an animation or progress bar on your splash overlay. My personal preference here is an indeterminate progress bar because it’s a common busy indicator throughout WP7 applications and the operating system. However, if you have an animation that fits in with your application and is visually engaging then you should definitely use that. For example, the Flickr application animates the blue and pink circles that form the logo.

To add a progress bar to your splash overlay, I highly recommend using the PerformanceProgressBar from the Silverlight Toolkit for WP7 because it overcomes an issue with the default progress bar and provides much better performance (hence the name!) by running on the compositor thread instead of the UI thread. So you’ll need to add a reference to Microsoft.Phone.Controls.Toolkit.dll, and then add an XML namespace reference for the Microsoft.Phone.Controls namespace. Your overlay XAML will then look like the following:

<phone:PhoneApplicationPage 
    x:Class="DerekLakin.WP7Trenches.Splash.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="False">
    <Grid x:Name="LayoutRoot" Background="Transparent">
        // Your normal page content goes here.
        <Image x:Name="_overlay" Source="/SplashScreenImage.jpg" />
        <toolkit:PerformanceProgressBar x:Name="_progress"
                                        VerticalAlignment="Center"
                                        IsIndeterminate="True" />
    </Grid>
</phone:PhoneApplicationPage>

In this example the progress bar will use the accent color that the user has specified on their device. If there is a possibility that this could be difficult to see on top of your splash screen image, then you can force a particular color by specifying it in the Foreground property.

You then need to update the LoadComplete method in your code-behind to additionally hide the progress bar on completion as shown below.

private void LoadComplete()
{
    this._overlay.Visibility = Visibility.Collapsed;
    this._progress.Visibility = Visibility.Collapsed;

    this.SupportedOrientations = 
        SupportedPageOrientation.PortraitOrLandscape;

    // Uncomment the following line if you want the system tray.
    // SystemTray.IsVisible = true;
}

Wrapping Up

In summary:

  • NEVER use the default splash screen.
  • If you don’t need one, don’t use a splash screen and your application will load even faster.
  • If you need a splash screen:
    • Be imaginative and create a visually appealing one.
    • Use the same image in an overlay on the first page if your app takes longer than 5 seconds to load.
    • Consider adding a progress bar or animation to show the user your app is doing something.
  • Your app still MUST be responsive to user input within 20 seconds no matter how flashy your splash screen is.
Advertisements