Construire un splashscreen de toute beauté pour Windows Phone !

Après un billet de (mauvaise) humeur, il est temps de revenir à la technique.

Aujourd’hui nous apprendrons comment créer un splashscreen qui s’intègre parfaitement à nos applications.

Mais avant tout qu’est qu’un splashscreen ?

C’est généralement une image qui s’affiche permettant de faire patienter l’utilisateur pendant que l’application se prépare à être lancée.


Le splashscreen par défaut


Lorsque l’on crée une application par défaut pour Windows phone, un splashscreen est déjà implementé.
Aucun code n’est nécessaire pour le faire fonctionner, Il s’agit seulement d’une image dont le nom est SplashScreenImage.jpg et dont la propriété « Build Action » est fixée à Content.

Lorsque l’application est lancée une animation de type flip est effectuée.

Il est à noter que pour de petites applications, un splashscreen n’est pas nécessaire.

En effet celui-ci disparait une fois le constructeur de la Mainpage lancé.
Dans le constructeur on trouve la méthode InitializeComponent qui est chargé d’instancier tous les controls de la page.

Si l’instanciation est trop rapide le splashscreen disparaitra avant d’avoir pu effectuer proprement son animation ce qui donnera à l’utilisateur un sentiment de flash désagréable.

Si c’est votre cas, vous pouvez retirer l’image SplashScreenImage.jpg de votre projet (il n’y aura plus de splashscreen alors).
Si en revanche vous désirez conserver un splashscreen vous pouvez allonger artificiellement la vie du constructeur en le freezant durant 500ms par exemple. L’animation étant assurée par l’OS et non Silverlight, elle continuera à s’executer sans saccade :

// Constructor
public MainPage()
{
  InitializeComponent();

  // on attends 500ms
  Thread.Sleep(500);
}


Embellir son splashscreen


Ce qui est ennuyeux avec le splashscreen par défaut c’est qu’une fois l’animation terminée, il disparait immédiatement.
Nous allons donc tenter d’effectuer une sortie plus élégante à l’aide des deux méthodes décrites ci-dessous.


Methode 1 : Sortie simple avec Image


Cette première méthode, la plus simple, consiste à cloner l’image du SplashScreen à la racine du projet puis à l’afficher en premier plan de notre XAML afin de faire croire à l’utilisateur qu’il s’agit de la même image.

Cette nouvelle image devra avoir sa propriété « Build Action » affecté à « Resource » pour éviter les temps de chargement trop long au niveau du XAML.

On l’appellera SplashScreenImageResource.jpg dans notre exemple.

Une fois l’image du splashscreen originelle retirée, on a plus qu’à animer notre propre image à partir de la méthode Load (ici une simple animation d’opacité)

ce qui nous donne en XAML :


<Grid x:Name="LayoutRoot">

  <Grid.Resources>
  <!-- Storyboard d'opacité -->
    <Storyboard x:Name="StoryboardVisibility">
      <DoubleAnimation From="1" To="0" Storyboard.TargetName="SplashScreen" Storyboard.TargetProperty="Opacity"></DoubleAnimation>  
    </Storyboard>
  </Grid.Resources>

  <!-- ici vos controles XAML -->

  <Image x:Name="SplasCreen" Source="SplashScreenImageResource.jpg">

</Grid>

et coté C# :

// Constructor
public MainPage()
{
    InitializeComponent();

    // on attends 500ms car l'initializeComponent est trop rapide quand peu de composant
    Thread.Sleep(500);

    this.StoryboardVisibility.Completed += new EventHandler(StoryboardVisibility_Completed);
    this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}

void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    this.StoryboardVisibility.BeginTime = TimeSpan.FromMilliseconds(500);
    this.StoryboardVisibility.Begin();
}

void StoryboardVisibility_Completed(object sender, EventArgs e)
{
    // on retire l'image du splashscreen
    this.LayoutRoot.Children.Remove(this.SplashScreen);
}

Vous pouvez télécharger la solution en cliquant ici

Si vous prenez l’article en cours n’oubliez pas d’aller jeter un coup d’oeil au paragraphe consacré à « la barre de l’heure ».


Methode 2 : Sortie complexe avec XAML


La deuxième méthode permet d’effectuer des effets de sortie beaucoup plus complexes.
Elle consiste à construire une animation en XAML puis de capturer la premiere frame de celle ci afin de s’en servir comme image de SplashScreen.
J’ai utilisé cette technique dans l’application « Friend Roulette » ( http://www.windowsphone.com/s?appId=f2be43a1-1b2d-43a4-816e-1f820cc3d760 ) et cela donne un réel dynamisme à l’application.

Commençons par créer le XAML et l’animation :

Nous allons mettre en place deux rectangles gris qui sortiront respectivement par le haut et par le bas tandis que le titre au centre disparaitre par un jeu d’opacité.

<Grid x:Name="LayoutRoot">

    <Grid.Resources>
        <Storyboard x:Name="StoryboardSplashScreen" SpeedRatio="2">
            <DoubleAnimation From="1" To="0" Storyboard.TargetName="Part1" Storyboard.TargetProperty="Opacity"></DoubleAnimation>
            <DoubleAnimation From="0" To="-400" Storyboard.TargetName="Part0Composite" Storyboard.TargetProperty="TranslateY"></DoubleAnimation>
            <DoubleAnimation From="0" To="400" Storyboard.TargetName="Part2Composite" Storyboard.TargetProperty="TranslateY"></DoubleAnimation>
        </Storyboard>
    </Grid.Resources>

    <!-- ici vos controles XAML -->

    <!-- SplashScreen -->
    <Grid x:Name="SplashScreen">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
            
        <Rectangle Grid.Row="0" Fill="#202020">
            <Rectangle.RenderTransform>
                <CompositeTransform x:Name="Part0Composite" TranslateY="0"></CompositeTransform>
            </Rectangle.RenderTransform>
        </Rectangle>

        <Border x:Name="Part1" BorderThickness="0,10,0,10"  BorderBrush="Black" Grid.Row="1" Background="Yellow">
            <TextBlock Text="SPLASHSCREEN" Foreground="Black" FontSize="40" FontFamily="Segoe WP Black" HorizontalAlignment="Center"></TextBlock>
        </Border>

        <Rectangle Grid.Row="2" Fill="#202020">
            <Rectangle.RenderTransform>
                <CompositeTransform x:Name="Part2Composite" TranslateY="0"></CompositeTransform>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Grid>

</Grid>

Puis avant de mettre en place le lancement du storyboard effectuons une capture d’écran de l’émulateur afin de créer l’image du SplashScreen.
N’oubliez pas de passer la taille de votre emulateur à 100% pour avoir les dimensions correctes de votre image (480×800). Ensuite comme l’émulateur ne sauve les captures qu’au format png, effectuez une conversion en jpg et renommez le fichier en « SplashScreenImage.jpg ».
Enfin, remplacez l’image original du SplashScreen par celle que l’on vient de créer en vérifiant que sa propriété « Action Build » est bien affectée à « Content ».

Il ne nous reste plus qu’à lancer le storyboard comme suit :

        public MainPage()
        {
            InitializeComponent();

            Thread.Sleep(500);

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.StoryboardSplashScreen.Begin();
        }

Il ne vous reste plus qu’a retire les XAML du splashscreen proprement (j’ai oublié de le faire dans l’exemple :/ )
Vous pouvez télécharger la solution en cliquant ici


L’attente


Si votre chargement dure vraiment longtemps il est possible de rajouter un contrôle progressbar à l’ensemble quelque soit la méthode (dans la méthode 1 il faudra animer un Grid contenant l’image du splashscreen ainsi que la progressbar au lieu de l’image directement).
L’utilisation du SystemTray.ProgressIndicator du Shell peut aussi faciliter l’affichage de la progression car même si l’application est très occupé à se mettre en place l’indicateur de progression sera tout de même animé.


La barre de l’heure


N’oubliez que si votre application utilise la barre de l’heure (ce qui est le cas par défaut), Notre splashcreen image (ou xaml) pourrait être décalé des 16 pixels qui la constitue.
Pour contre cette effet on lui indique que l’opacité de la barre doit être à 0 (et donc prise en compte par notre application et plus par le système).

<phone:PhoneApplicationPage
...
shell:SystemTray.IsVisible="True" 
shell:SystemTray.Opacity="0"
>
...
</<phone:PhoneApplicationPage>

Ensuite il suffit de réserver un emplacement de 16 pixels dans notre XAML.


Conclusion


Grâce aux deux méthodes que l’on vient de voir, vous pouvez constater qu’il est rapide d’ajouter un SplashScreen élaboré.
Plus d’excuse pour ne pas rendre vos entrées d’application sexy !



leave your comment