Compartilhar via


Exibir uma tela inicial por mais tempo

Exiba uma tela inicial por mais tempo criando uma tela inicial estendida para o seu aplicativo. Essa tela estendida imita a tela inicial mostrada quando seu aplicativo é iniciado, mas pode ser personalizada. Se você deseja mostrar informações de carregamento em tempo real ou simplesmente dar ao seu aplicativo tempo extra para preparar sua interface inicial, uma tela inicial estendida permite definir a experiência de inicialização.

Observação

A frase "tela inicial estendida" neste tópico refere-se a uma tela inicial que permanece na tela por um longo período de tempo. Isso não significa uma subclasse derivada da classe SplashScreen .

APIs importantes

As seguintes APIs são usadas neste tópico:

Recomendações de tela inicial padrão

Certifique-se de que sua tela inicial estendida imite com precisão a tela inicial padrão seguindo estas recomendações:

  • Sua página de tela inicial estendida deve usar uma imagem de 620 x 300 pixels que seja consistente com a imagem especificada para sua tela inicial no manifesto do aplicativo (a imagem da tela inicial do aplicativo). No Microsoft Visual Studio, as configurações da tela inicial são armazenadas na seção Tela Inicial da guia Ativos Visuais no manifesto do aplicativo (arquivo Package.appxmanifest).
  • A tela inicial estendida deve usar uma cor de plano de fundo consistente com a cor de plano de fundo especificada para a tela inicial no manifesto do aplicativo (o plano de fundo da tela inicial do aplicativo).
  • Seu código deve usar a classe SplashScreen para posicionar a imagem da tela inicial do aplicativo nas mesmas coordenadas de tela que a tela inicial padrão.
  • Seu código deve responder a eventos de redimensionamento de janela (como quando a tela é girada ou seu aplicativo é movido ao lado de outro aplicativo na tela) usando a classe SplashScreen para reposicionar itens em sua tela inicial estendida.

Use as etapas a seguir para criar uma tela inicial estendida que imite efetivamente a tela inicial padrão.

Adicionar um item de Página em Branco ao seu aplicativo existente

Este tópico pressupõe que você deseja adicionar uma tela inicial estendida a um projeto de aplicativo UWP (Plataforma Universal do Windows) existente usando C#, Visual Basic ou C++.

  • Abra o aplicativo no Visual Studio.
  • Pressione ou abra o Project na barra de menus e clique em Adicionar Novo Item. Uma caixa de diálogo Adicionar novo item será exibida.
  • Nessa caixa de diálogo, adicione uma nova página em branco ao seu aplicativo. Este tópico nomeia a página da tela inicial estendida como "ExtendedSplash".

A adição de um item de Página em Branco gera dois arquivos, um para marcação (ExtendedSplash.xaml) e outro para código (ExtendedSplash.xaml.cs).

XAML essencial para uma tela inicial estendida

Siga estas etapas para adicionar uma imagem e um controle de progresso à tela inicial estendida.

No arquivo ExtendedSplash.xaml:

  • Altere a propriedade Background do elemento Grid padrão para corresponder à cor da tela de fundo definida para a tela inicial do aplicativo no manifesto do aplicativo (na seção Ativos Visuais do arquivo Package.appxmanifest). A cor padrão da tela inicial é cinza claro (valor hexadecimal #464646). Observe que esse elemento Grid é fornecido por padrão quando você cria uma nova página em branco. Você não precisa usar um Grid; é apenas uma base conveniente para criar uma tela inicial estendida.
  • Adicione um elemento Canvas à Grade. Você usará esse Canvas para posicionar sua imagem de tela inicial estendida.
  • Adicione um elemento Image ao Canvas. Use a mesma imagem de 620 x 300 pixels para a tela inicial estendida que você escolheu para a tela inicial padrão.
  • (Opcional) Adicione um controle de progresso para mostrar aos usuários que seu aplicativo está sendo carregado. Este tópico adiciona um ProgressRing, em vez de um ProgressBar determinado ou indeterminado.

O exemplo a seguir demonstra uma Grid com essas adições e alterações.

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

Observação

Este exemplo define a largura do ProgressRing como 20 pixels. Você pode definir manualmente sua largura como um valor que funcione para seu aplicativo, no entanto, o controle não será renderizado em larguras inferiores a 20 pixels.

Código essencial para uma classe de tela inicial estendida

Sua tela inicial estendida precisa responder sempre que o tamanho da janela (somente Windows) ou a orientação for alterado. A posição da imagem que você usa deve ser atualizada para que sua tela inicial estendida tenha uma boa aparência, independentemente de como a janela muda.

Use estas etapas para definir métodos para exibir corretamente sua tela inicial estendida.

  1. Adicionar namespaces necessários

    Você precisará adicionar os namespaces a seguir ao ExtendedSplash.xaml.cs para acessar a classe SplashScreen, o struct Rect e os eventos Window.SizeChanged.

    using Windows.ApplicationModel.Activation;
    using Windows.Foundation;
    using Windows.UI.Core;
    
  2. Criar uma classe parcial e declarar variáveis de classe

    Inclua o código a seguir em ExtendedSplash.xaml.cs para criar uma classe parcial para representar uma tela inicial estendida.

    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
    }
    

    Essas variáveis de classe são usadas por vários métodos. A splashImageRect variável armazena as coordenadas em que o sistema exibiu a imagem da tela inicial do aplicativo. A splash variável armazena um objeto SplashScreen e a variável rastreia dismissed se a tela inicial exibida pelo sistema foi ou não descartada.

  3. Defina um construtor para sua classe que posicione corretamente a imagem

    O código a seguir define um construtor para a classe de tela inicial estendida que escuta eventos de redimensionamento de janela, posiciona a imagem e o controle de progresso (opcional) na tela inicial estendida, cria um quadro para navegação e chama um método assíncrono para restaurar um estado de sessão salvo.

    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();            
    }
    

    Certifique-se de registrar seu manipulador Window.SizeChanged (ExtendedSplash_OnResize no exemplo) em seu construtor de classe para que seu aplicativo posicione a imagem corretamente em sua tela inicial estendida.

  4. Definir um método de classe para posicionar a imagem na tela inicial estendida

    Este código demonstra como posicionar a imagem na página de tela inicial estendida com a splashImageRect variável de classe.

    void PositionImage()
    {
        extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
        extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
        extendedSplashImage.Height = splashImageRect.Height;
        extendedSplashImage.Width = splashImageRect.Width;
    }
    
  5. (Opcional) Definir um método de classe para posicionar um controle de progresso na tela inicial estendida

    Se você optar por adicionar um ProgressRing à tela inicial estendida, posicione-o em relação à imagem da tela inicial. Adicione o código a seguir ao ExtendedSplash.xaml.cs para centralizar o ProgressRing 32 pixels abaixo da imagem.

    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. Dentro da classe, defina um manipulador para o evento Dismissed

    No ExtendedSplash.xaml.cs, responda quando o evento SplashScreen.Dismissed ocorrer definindo a dismissed variável de classe como true. Se o aplicativo tiver operações de instalação, adicione-as a esse manipulador de eventos.

    // 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...
    }
    

    Após a conclusão da configuração do aplicativo, saia da tela inicial estendida. O código a seguir define um método chamado DismissExtendedSplash que navega até o MainPage definido no arquivo MainPage.xaml do aplicativo.

    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. Dentro da classe, defina um manipulador para eventos Window.SizeChanged

    Prepare sua tela inicial estendida para reposicionar seus elementos se um usuário redimensionar a janela. Esse código responde quando um evento Window.SizeChanged ocorre capturando as novas coordenadas e reposicionando a imagem. Se você adicionou um controle de progresso à tela inicial estendida, reposicione-o dentro desse manipulador de eventos também.

    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();
        }
    }
    

    Observação

     Antes de tentar obter o local da imagem, verifique se a variável de classe (splash) contém um objeto SplashScreen válido, conforme mostrado no exemplo.

     

  8. (Opcional) Adicionar um método de classe para restaurar um estado de sessão salvo

    O código adicionado ao método OnLaunched na Etapa 4: Modificar o manipulador de ativação de inicialização faz com que seu aplicativo exiba uma tela inicial estendida quando ele é iniciado. Para consolidar todos os métodos relacionados à inicialização do aplicativo em sua classe de tela inicial estendida, você pode considerar adicionar um método ao arquivo ExtendedSplash.xaml.cs para restaurar o estado do aplicativo.

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

    Ao modificar o manipulador de ativação de inicialização no App.xaml.cs, você também loadstate definirá como true se o ApplicationExecutionState anterior do seu aplicativo tiver sido Terminated. Nesse caso, o método restaura RestoreState o aplicativo para seu estado anterior. Para obter uma visão geral da inicialização, suspensão e encerramento do aplicativo, consulte Ciclo de vida do aplicativo.

Modificar o manipulador de ativação de inicialização

Quando seu aplicativo é iniciado, o sistema passa informações da tela inicial para o manipulador de eventos de ativação de inicialização do aplicativo. Você pode usar essas informações para posicionar corretamente a imagem na página da tela inicial estendida. Você pode obter essas informações da tela inicial dos argumentos do evento de ativação que são passados para o manipulador OnLaunched do aplicativo (consulte a args variável no código a seguir).

Se você ainda não substituiu o manipulador OnLaunched do seu aplicativo, consulte Ciclo de vida do aplicativo para saber como lidar com eventos de ativação.

Em App.xaml.cs, adicione o código a seguir para criar e exibir uma tela inicial estendida.

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();
}

Código completo

O código a seguir difere um pouco dos snippets mostrados nas etapas anteriores.

  • ExtendedSplash.xaml inclui um DismissSplash botão. Quando esse botão é clicado, um manipulador de eventos, DismissSplashButton_Click, chama o DismissExtendedSplash método. Em seu aplicativo, chame DismissExtendedSplash quando o aplicativo terminar de carregar recursos ou inicializar sua interface do usuário.
  • Esse aplicativo também usa um modelo de projeto de aplicativo UWP, que usa a navegação de quadro . Como resultado, em App.xaml.cs, o manipulador de ativação de inicialização (OnLaunched) define um rootFrame e o usa para definir o conteúdo da janela do aplicativo.

ExtendedSplash.xaml

Este exemplo inclui um DismissSplash botão porque ele não tem recursos de aplicativo para carregar. Em seu aplicativo, ignore a tela inicial estendida automaticamente quando seu aplicativo terminar de carregar recursos ou preparar sua interface inicial.

<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

Observe que o DismissExtendedSplash método é chamado do manipulador de eventos de clique para o DismissSplash botão. Em seu aplicativo, você não precisará de um DismissSplash botão. Em vez disso, chame DismissExtendedSplash quando seu aplicativo terminar de carregar recursos e você quiser navegar até a página principal.

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

Esse projeto foi criado usando o modelo de projeto XAML (Aplicativo em Branco) do aplicativo UWP no Visual Studio. Os manipuladores de eventos e OnSuspending são OnNavigationFailed gerados automaticamente e não precisam ser alterados para implementar uma tela inicial estendida. Este tópico modifica apenas OnLaunched.

Se você não usou um modelo de projeto para seu aplicativo, consulte Etapa 4: modificar o manipulador de ativação de inicialização para obter um exemplo de uma modificação OnLaunched que não usa a navegação de quadro .

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();
        }
    }
}

Referência