Visualizzare una schermata iniziale per un periodo di tempo più lungo

Visualizzare una schermata iniziale più a lungo creando una schermata iniziale estesa per un'app. Questa schermata estesa imita la schermata iniziale visualizzata all'avvio dell'app, ma può essere personalizzata. Se vuoi mostrare informazioni di caricamento in tempo reale o semplicemente assegnare alla tua app tempo aggiuntivo per preparare l'interfaccia utente iniziale, una schermata iniziale estesa ti consente di definire l'esperienza di avvio.

Nota

La frase "schermata iniziale estesa" in questo argomento si riferisce a una schermata iniziale che rimane sullo schermo per un lungo periodo di tempo. Non si tratta di una sottoclasse che deriva dalla classe SplashScreen .

API importanti

Le API seguenti vengono usate in questo argomento:

Raccomandazioni predefinite per la schermata iniziale

Assicurati che la schermata iniziale estesa imiti accuratamente la schermata iniziale predefinita seguendo questi consigli:

  • La pagina della schermata iniziale estesa deve usare un'immagine da 620 x 300 pixel coerente con l'immagine specificata per la schermata iniziale nel manifesto dell'app (immagine della schermata iniziale dell'app). In Microsoft Visual Studio le impostazioni della schermata iniziale vengono archiviate nella sezione Schermata iniziale della scheda Asset visivi del manifesto dell'app (file Package.appxmanifest).
  • La schermata iniziale estesa deve usare un colore di sfondo coerente con il colore di sfondo specificato per la schermata iniziale nel manifesto dell'app (sfondo della schermata iniziale dell'app).
  • Il codice deve usare la classe SplashScreen per posizionare l'immagine della schermata iniziale dell'app con le stesse coordinate dello schermo della schermata iniziale predefinita.
  • Il codice deve rispondere agli eventi di ridimensionamento della finestra (ad esempio quando lo schermo viene ruotato o l'app viene spostata accanto a un'altra app sullo schermo) usando la classe SplashScreen per riposizionare gli elementi nella schermata iniziale estesa.

Usare la procedura seguente per creare una schermata iniziale estesa che imita efficacemente la schermata iniziale predefinita.

Aggiungere un elemento Pagina vuota all'app esistente

Questo argomento presuppone che si voglia aggiungere una schermata iniziale estesa a un progetto di app UWP (piattaforma UWP (Universal Windows Platform)) esistente usando C#, Visual Basic o C++.

  • Apri l'app in Visual Studio.
  • Premere o aprire Progetto dalla barra dei menu e fare clic su Aggiungi nuovo elemento. Verrà visualizzata la finestra di dialogo Aggiungi nuovo elemento.
  • Da questa finestra di dialogo aggiungere una nuova pagina vuota all'app. Questo argomento denomina la pagina della schermata iniziale estesa "ExtendedSplash".

L'aggiunta di un elemento Pagina vuota genera due file, uno per il markup (ExtendedSplash.xaml) e un altro per il codice (ExtendedSplash.xaml.cs).

XAML essenziale per una schermata iniziale estesa

Seguire questa procedura per aggiungere un'immagine e un controllo di stato alla schermata iniziale estesa.

Nel file ExtendedSplash.xaml:

  • Modificare la proprietà Background dell'elemento griglia predefinito in modo che corrisponda al colore di sfondo impostato per la schermata iniziale dell'app nel manifesto dell'app (nella sezione Asset visivi del file Package.appxmanifest). Il colore predefinito della schermata iniziale è grigio chiaro (valore esadecimale #464646). Si noti che questo elemento griglia viene fornito per impostazione predefinita quando si crea una nuova pagina vuota. Non è necessario usare una griglia, ma è solo una base comoda per la creazione di una schermata iniziale estesa.
  • Aggiungere un elemento Canvas alla griglia. Questa area di disegno verrà usata per posizionare l'immagine estesa della schermata iniziale.
  • Aggiungere un elemento Image all'oggetto Canvas. Usa la stessa immagine da 620 x 300 pixel per la schermata iniziale estesa scelta per la schermata iniziale predefinita.
  • (Facoltativo) Aggiungere un controllo di stato per mostrare agli utenti che l'app sta caricando. In questo argomento viene aggiunto un progressRing anziché un progressbar determinato o indeterminato.

Nell'esempio seguente viene illustrata una griglia con queste aggiunte e modifiche.

    <Grid Background="#464646">
        <Canvas>
            <Image x:Name="extendedSplashImage" Source="Assets/SplashScreen.png"/>
            <ProgressRing Name="splashProgressRing" IsActive="True" Width="20" HorizontalAlignment="Center"></ProgressRing>
        </Canvas>
    </Grid>

Nota

In questo esempio la larghezza di ProgressRing viene impostata su 20 pixel. Puoi impostarne manualmente la larghezza su un valore che funziona per la tua app, ma il controllo non eseguirà il rendering a larghezze inferiori a 20 pixel.

Codice essenziale per una classe della schermata iniziale estesa

La schermata iniziale estesa deve rispondere ogni volta che le dimensioni della finestra (solo Windows) o l'orientamento cambiano. La posizione dell'immagine usata deve essere aggiornata in modo che la schermata iniziale estesa abbia un aspetto ottimale indipendentemente dal modo in cui cambia la finestra.

Usare questi passaggi per definire i metodi per visualizzare correttamente la schermata iniziale estesa.

  1. Aggiungere gli spazi dei nomi obbligatori

    È necessario aggiungere gli spazi dei nomi seguenti a ExtendedSplash.xaml.cs per accedere alla classe SplashScreen a Rect struct e agli eventi Window.SizeChanged.

    using Windows.ApplicationModel.Activation;
    using Windows.Foundation;
    using Windows.UI.Core;
    
  2. Creare una classe parziale e dichiarare le variabili di classe

    Includere il codice seguente in ExtendedSplash.xaml.cs per creare una classe parziale per rappresentare una schermata iniziale estesa.

    partial class ExtendedSplash : Page
    {
        internal Rect splashImageRect; // Rect to store splash screen image coordinates.
        private SplashScreen splash; // Variable to hold the splash screen object.
        internal bool dismissed = false; // Variable to track splash screen dismissal status.
        internal Frame rootFrame;
    
       // Define methods and constructor
    }
    

    Queste variabili di classe vengono usate da diversi metodi. La variabile splashImageRect archivia le coordinate in cui il sistema visualizza l'immagine della schermata iniziale per l'app. La splash variabile archivia un oggetto SplashScreen e la dismissed variabile tiene traccia del fatto che la schermata iniziale visualizzata dal sistema sia stata chiusa.

  3. Definire un costruttore per la classe che posiziona correttamente l'immagine

    Il codice seguente definisce un costruttore per la classe della schermata iniziale estesa che ascolta gli eventi di ridimensionamento della finestra, posiziona l'immagine e il controllo di avanzamento (facoltativo) sulla schermata iniziale estesa, crea un frame per la navigazione e chiama un metodo asincrono per ripristinare una sessione salvata stato.

    public ExtendedSplash(SplashScreen splashscreen, bool loadState)
    {
        InitializeComponent();
    
        // Listen for window resize events to reposition the extended splash screen image accordingly.
        // This ensures that the extended splash screen formats properly in response to window resizing.
        Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);
    
        splash = splashscreen;
        if (splash != null)
        {
            // Register an event handler to be executed when the splash screen has been dismissed.
            splash.Dismissed += new TypedEventHandler<SplashScreen, Object>(DismissedEventHandler);
    
            // Retrieve the window coordinates of the splash screen image.
            splashImageRect = splash.ImageLocation;
            PositionImage();
    
            // If applicable, include a method for positioning a progress control.
            PositionRing();
        }
    
        // Create a Frame to act as the navigation context
        rootFrame = new Frame();            
    }
    

    Assicurati di registrare il gestore Window.SizeChanged (ExtendedSplash_OnResize nell'esempio) nel costruttore della classe in modo che l'app posizioni correttamente l'immagine nella schermata iniziale estesa.

  4. Definire un metodo di classe per posizionare l'immagine nella schermata iniziale estesa

    Questo codice illustra come posizionare l'immagine nella pagina della schermata iniziale estesa con la variabile di classe splashImageRect.

    void PositionImage()
    {
        extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
        extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
        extendedSplashImage.Height = splashImageRect.Height;
        extendedSplashImage.Width = splashImageRect.Width;
    }
    
  5. (Facoltativo) Definire un metodo di classe per posizionare un controllo di stato nella schermata iniziale estesa

    Se si sceglie di aggiungere un progressRing alla schermata iniziale estesa, posizionarlo rispetto all'immagine della schermata iniziale. Aggiungere il codice seguente per ExtendedSplash.xaml.cs al centro dell'immagine ProgressRing 32 pixel sotto l'immagine.

    void PositionRing()
    {
        splashProgressRing.SetValue(Canvas.LeftProperty, splashImageRect.X + (splashImageRect.Width*0.5) - (splashProgressRing.Width*0.5));
        splashProgressRing.SetValue(Canvas.TopProperty, (splashImageRect.Y + splashImageRect.Height + splashImageRect.Height*0.1));
    }
    
  6. All'interno della classe definire un gestore per l'evento Dismissed

    In ExtendedSplash.xaml.cs rispondere quando si verifica l'evento SplashScreen.Dismissed impostando la dismissed variabile di classe su true. Se l'app dispone di operazioni di configurazione, aggiungerle a questo gestore eventi.

    // Include code to be executed when the system has transitioned from the splash screen to the extended splash screen (application's first view).
    void DismissedEventHandler(SplashScreen sender, object e)
    {
        dismissed = true;
    
        // Complete app setup operations here...
    }
    

    Al termine dell'installazione dell'app, passare dalla schermata iniziale estesa. Il codice seguente definisce un metodo denominato DismissExtendedSplash che passa all'oggetto MainPage definito nel file MainPage.xaml dell'app.

    async void DismissExtendedSplash()
      {
         await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() =>            {
              rootFrame = new Frame();
              rootFrame.Content = new MainPage(); Window.Current.Content = rootFrame;
            });
      }
    
  7. All'interno della classe definire un gestore per gli eventi Window.SizeChanged

    Preparare la schermata iniziale estesa per riposizionare gli elementi se un utente ridimensiona la finestra. Questo codice risponde quando si verifica un evento Window.SizeChanged acquisendo le nuove coordinate e riposizionando l'immagine. Se è stato aggiunto un controllo di stato alla schermata iniziale estesa, riposizionarlo anche all'interno di questo gestore eventi.

    void ExtendedSplash_OnResize(Object sender, WindowSizeChangedEventArgs e)
    {
        // Safely update the extended splash screen image coordinates. This function will be executed when a user resizes the window.
        if (splash != null)
        {
            // Update the coordinates of the splash screen image.
            splashImageRect = splash.ImageLocation;
            PositionImage();
    
            // If applicable, include a method for positioning a progress control.
            // PositionRing();
        }
    }
    

    Nota

     Prima di provare a ottenere il percorso dell'immagine, assicurarsi che la variabile di classe (splash) contenga un oggetto SplashScreen valido, come illustrato nell'esempio.

     

  8. (Facoltativo) Aggiungere un metodo di classe per ripristinare uno stato sessione salvato

    Il codice aggiunto al metodo OnLaunched nel passaggio 4: Modificare il gestore di attivazione dell'avvio fa sì che l'app visualizzi una schermata iniziale estesa all'avvio. Per consolidare tutti i metodi correlati all'avvio dell'app nella classe della schermata iniziale estesa, puoi prendere in considerazione l'aggiunta di un metodo al file ExtendedSplash.xaml.cs per ripristinare lo stato dell'app.

    void RestoreState(bool loadState)
    {
        if (loadState)
        {
             // code to load your app's state here
        }
    }
    

    Quando modifichi il gestore di attivazione dell'avvio in App.xaml.cs, imposterai anche su loadstate true se l'oggetto ApplicationExecutionState precedente dell'app è stato Terminato. In tal caso, il metodo RestoreState ripristina lo stato precedente dell'app. Per una panoramica dell'avvio, della sospensione e della terminazione dell'app, vedi Ciclo di vita dell'app.

Modificare il gestore di attivazione dell'avvio

All'avvio dell'app, il sistema passa le informazioni della schermata iniziale al gestore eventi di attivazione dell'avvio dell'app. È possibile usare queste informazioni per posizionare correttamente l'immagine nella pagina della schermata iniziale estesa. Puoi ottenere queste informazioni sulla schermata iniziale dagli argomenti dell'evento di attivazione passati al gestore OnLaunched dell'app (vedi la args variabile nel codice seguente).

Se non è già stato eseguito l'override del gestore OnLaunched per l'app, vedere App lifecycle per informazioni su come gestire gli eventi di attivazione.

In App.xaml.cs aggiungere il codice seguente per creare e visualizzare una schermata iniziale estesa.

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    if (args.PreviousExecutionState != ApplicationExecutionState.Running)
    {
        bool loadState = (args.PreviousExecutionState == ApplicationExecutionState.Terminated);
        ExtendedSplash extendedSplash = new ExtendedSplash(args.SplashScreen, loadState);
        Window.Current.Content = extendedSplash;
    }

    Window.Current.Activate();
}

Codice completo

Il codice seguente differisce leggermente dai frammenti di codice illustrati nei passaggi precedenti.

  • ExtendedSplash.xaml include un pulsante DismissSplash. Quando si fa clic su questo pulsante, un gestore eventi, DismissSplashButton_Click, chiama il metodo DismissExtendedSplash. Nell'app chiamare DismissExtendedSplash quando l'app ha completato il caricamento delle risorse o l'inizializzazione dell'interfaccia utente.
  • Questa app usa anche un modello di progetto di app UWP, che usa lo spostamento frame. Di conseguenza, in App.xaml.cs, il gestore di attivazione di avvio (OnLaunched) definisce un rootFrame oggetto e lo usa per impostare il contenuto della finestra dell'app.

ExtendedSplash.xaml

Questo esempio include un pulsante DismissSplash perché non include risorse dell'app da caricare. Nell'app ignorare automaticamente la schermata iniziale estesa al termine del caricamento delle risorse o della preparazione dell'interfaccia utente iniziale.

<Page
    x:Class="SplashScreenExample.ExtendedSplash"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SplashScreenExample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="#464646">
        <Canvas>
            <Image x:Name="extendedSplashImage" Source="Assets/SplashScreen.png"/>
            <ProgressRing Name="splashProgressRing" IsActive="True" Width="20" HorizontalAlignment="Center"/>
        </Canvas>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Bottom">
            <Button x:Name="DismissSplash" Content="Dismiss extended splash screen" HorizontalAlignment="Center" Click="DismissSplashButton_Click" />
        </StackPanel>
    </Grid>
</Page>

ExtendedSplash.xaml.cs

Si noti che il metodo DismissExtendedSplash viene chiamato dal gestore eventi Click per il pulsante DismissSplash. Nell'app non è necessario un pulsante DismissSplash. Al contrario, chiamare DismissExtendedSplash quando l'app ha completato il caricamento delle risorse e si vuole passare alla relativa pagina principale.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

using Windows.ApplicationModel.Activation;
using SplashScreenExample.Common;
using Windows.UI.Core;

// The Blank Page item template is documented at https://go.microsoft.com/fwlink/p/?LinkID=234238

namespace SplashScreenExample
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    partial class ExtendedSplash : Page
    {
        internal Rect splashImageRect; // Rect to store splash screen image coordinates.
        private SplashScreen splash; // Variable to hold the splash screen object.
        internal bool dismissed = false; // Variable to track splash screen dismissal status.
        internal Frame rootFrame;

        public ExtendedSplash(SplashScreen splashscreen, bool loadState)
        {
            InitializeComponent();

            // Listen for window resize events to reposition the extended splash screen image accordingly.
            // This is important to ensure that the extended splash screen is formatted properly in response to snapping, unsnapping, rotation, etc...
            Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);

            splash = splashscreen;

            if (splash != null)
            {
                // Register an event handler to be executed when the splash screen has been dismissed.
                splash.Dismissed += new TypedEventHandler<SplashScreen, Object>(DismissedEventHandler);

                // Retrieve the window coordinates of the splash screen image.
                splashImageRect = splash.ImageLocation;
                PositionImage();

                // Optional: Add a progress ring to your splash screen to show users that content is loading
                PositionRing();
            }

            // Create a Frame to act as the navigation context
            rootFrame = new Frame();

            // Restore the saved session state if necessary
            RestoreState(loadState);
        }

        void RestoreState(bool loadState)
        {
            if (loadState)
            {
                // TODO: write code to load state
            }
        }

        // Position the extended splash screen image in the same location as the system splash screen image.
        void PositionImage()
        {
            extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
            extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
            extendedSplashImage.Height = splashImageRect.Height;
            extendedSplashImage.Width = splashImageRect.Width;

        }

        void PositionRing()
        {
            splashProgressRing.SetValue(Canvas.LeftProperty, splashImageRect.X + (splashImageRect.Width*0.5) - (splashProgressRing.Width*0.5));
            splashProgressRing.SetValue(Canvas.TopProperty, (splashImageRect.Y + splashImageRect.Height + splashImageRect.Height*0.1));
        }

        void ExtendedSplash_OnResize(Object sender, WindowSizeChangedEventArgs e)
        {
            // Safely update the extended splash screen image coordinates. This function will be fired in response to snapping, unsnapping, rotation, etc...
            if (splash != null)
            {
                // Update the coordinates of the splash screen image.
                splashImageRect = splash.ImageLocation;
                PositionImage();
                PositionRing();
            }
        }

        // Include code to be executed when the system has transitioned from the splash screen to the extended splash screen (application's first view).
        void DismissedEventHandler(SplashScreen sender, object e)
        {
            dismissed = true;

            // Complete app setup operations here...
        }

        void DismissExtendedSplash()
        {
            // Navigate to mainpage
            rootFrame.Navigate(typeof(MainPage));
            // Place the frame in the current Window
            Window.Current.Content = rootFrame;
        }

        void DismissSplashButton_Click(object sender, RoutedEventArgs e)
        {
            DismissExtendedSplash();
        }
    }
}

App.xaml.cs

Questo progetto è stato creato usando il modello di progetto dell'app UWP App vuota (XAML) in Visual Studio. I gestori eventi OnNavigationFailed e OnSuspending vengono generati automaticamente e non devono essere modificati per implementare una schermata iniziale estesa. Questo argomento modifica solo OnLaunched.

Se non hai usato un modello di progetto per la tua app, vedi Passaggio 4: Modificare il gestore di attivazione dell'avvio per un esempio di modifica OnLaunched che non usa lo spostamento Frame.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The Blank Application template is documented at https://go.microsoft.com/fwlink/p/?LinkID=234227

namespace SplashScreenExample
{
    /// <summary>
    /// Provides application-specific behavior to supplement the default Application class.
    /// </summary>
    sealed partial class App : Application
    {
        /// <summary>
        /// Initializes the singleton application object.  This is the first line of authored code
        /// executed, and as such is the logical equivalent of main() or WinMain().
        /// </summary>
        public App()
        {
            Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
            Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
            Microsoft.ApplicationInsights.WindowsCollectors.Session);
            this.InitializeComponent();
            this.Suspending += OnSuspending;
        }

        /// <summary>
        /// Invoked when the application is launched normally by the end user.  Other entry points
        /// will be used such as when the application is launched to open a specific file.
        /// </summary>
        /// <param name="e">Details about the launch request and process.</param>
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();
                // Set the default language
                rootFrame.Language = Windows.Globalization.ApplicationLanguages.Languages[0];

                rootFrame.NavigationFailed += OnNavigationFailed;

                //  Display an extended splash screen if app was not previously running.
                if (e.PreviousExecutionState != ApplicationExecutionState.Running)
                {
                    bool loadState = (e.PreviousExecutionState == ApplicationExecutionState.Terminated);
                    ExtendedSplash extendedSplash = new ExtendedSplash(e.SplashScreen, loadState);
                    rootFrame.Content = extendedSplash;
                    Window.Current.Content = rootFrame;
                }
            }

            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
            // Ensure the current window is active
            Window.Current.Activate();
        }

        /// <summary>
        /// Invoked when Navigation to a certain page fails
        /// </summary>
        /// <param name="sender">The Frame which failed navigation</param>
        /// <param name="e">Details about the navigation failure</param>
        void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
        {
            throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
        }

        /// <summary>
        /// Invoked when application execution is being suspended.  Application state is saved
        /// without knowing whether the application will be terminated or resumed with the contents
        /// of memory still intact.
        /// </summary>
        /// <param name="sender">The source of the suspend request.</param>
        /// <param name="e">Details about the suspend request.</param>
        private void OnSuspending(object sender, SuspendingEventArgs e)
        {
            var deferral = e.SuspendingOperation.GetDeferral();
            // TODO: Save application state and stop any background activity
            deferral.Complete();
        }
    }
}

Riferimento