Compartir a través de


Mostrar una pantalla de inicio durante más tiempo

Muestre una pantalla de presentación durante más tiempo mediante la creación de una pantalla de presentación extendida para la aplicación. Esta pantalla extendida imita la pantalla de presentación que se muestra cuando se inicia la aplicación, pero se puede personalizar. Tanto si quieres mostrar información de carga en tiempo real como si simplemente proporcionas tiempo adicional a la aplicación para preparar su interfaz de usuario inicial, una pantalla de presentación extendida te permite definir la experiencia de inicio.

Nota:

La frase "pantalla de presentación extendida" de este tema hace referencia a una pantalla de presentación que permanece en la pantalla durante un período de tiempo prolongado. No significa una subclase que deriva de la clase SplashScreen.

API importantes

En este tema se usan las SIGUIENTES API:

Recomendaciones de pantalla de presentación predeterminadas

Asegúrese de que la pantalla de presentación extendida imita con precisión la pantalla de presentación predeterminada siguiendo estas recomendaciones:

  • La página de pantalla de presentación extendida debe usar una imagen de 620 x 300 píxeles que sea coherente con la imagen especificada para la pantalla de presentación en el manifiesto de la aplicación (imagen de pantalla de presentación de la aplicación). En Microsoft Visual Studio, la configuración de la pantalla de presentación se almacena en la sección Pantalla de presentación de la pestaña Activos visuales del manifiesto de la aplicación (archivo Package.appxmanifest).
  • La pantalla de presentación extendida debe usar un color de fondo coherente con el color de fondo especificado para la pantalla de presentación en el manifiesto de la aplicación (fondo de la pantalla de presentación de la aplicación).
  • El código debe usar la clase SplashScreen para colocar la imagen de la pantalla de presentación de la aplicación en las mismas coordenadas de pantalla que la pantalla de presentación predeterminada.
  • El código debe responder a eventos de cambio de tamaño de ventana (por ejemplo, cuando se gira la pantalla o la aplicación se mueve junto a otra aplicación en pantalla) mediante el uso de la clase SplashScreen para cambiar la posición de los elementos en la pantalla de presentación extendida.

Siga estos pasos para crear una pantalla de presentación extendida que imita eficazmente la pantalla de presentación predeterminada.

Añade un elemento de página en blanco a tu aplicación existente

En este tema se supone que quieres agregar una pantalla de presentación extendida a un proyecto de aplicación de la Plataforma universal de Windows (UWP) existente mediante C#, Visual Basic o C++.

  • Abra la aplicación en Visual Studio.
  • Presione o abra Project en la barra de menús y haga clic en Agregar nuevo elemento. Aparecerá un cuadro de diálogo Agregar nuevo elemento.
  • En este cuadro de diálogo, agrega una nueva página en blanco a tu aplicación. Este tema denomina a la página de inicio extendida como "ExtendedSplash".

Al agregar un elemento de página en blanco genera dos archivos, uno para el markup (ExtendedSplash.xaml) y otro para el código (ExtendedSplash.xaml.cs).

XAML esencial para una pantalla de inicio extendida

Siga estos pasos para agregar una imagen y un control de progreso a la pantalla de presentación extendida.

En el archivo ExtendedSplash.xaml:

  • Cambie la propiedad Background del elemento Grid predeterminado para que coincida con el color de fondo establecido para la pantalla de presentación de la aplicación en el manifiesto de la aplicación (en la sección Visual Assets del archivo Package.appxmanifest). El color predeterminado de la pantalla de presentación es un gris claro (valor hexadecimal #464646). Tenga en cuenta que este elemento de cuadrícula se proporciona de forma predeterminada al crear una nueva página en blanco. No es necesario usar una Grid; es simplemente una base cómoda para crear una pantalla de presentación extendida.
  • Agregue un elemento Canvas al Grid. Usará este Canvas para colocar la imagen de la pantalla de presentación extendida.
  • Agregue un elemento de imagen al lienzo . Utilice la misma imagen de 620 x 300 píxeles para la pantalla de presentación extendida que hayas elegido para la pantalla de presentación predeterminada.
  • (Opcional) Agregue un control de progreso para mostrar a los usuarios que la aplicación está cargando. En este tema se agrega un ProgressRing, en lugar de un ProgressBardeterminado o indeterminado.

El ejemplo siguiente demuestra una rejilla de con estas adiciones y cambios.

    <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:

En este ejemplo se establece el ancho del ProgressRing en 20 píxeles. Puede establecer manualmente su ancho en un valor que funcione para la aplicación; sin embargo, el control no se representará en anchos de menos de 20 píxeles.

Código esencial para una clase de pantalla de presentación extendida

La pantalla de presentación extendida debe responder siempre que cambie el tamaño de la ventana (solo Windows) o la orientación. La posición de la imagen que use debe actualizarse para que la pantalla de presentación extendida se vea bien independientemente de cómo cambie la ventana.

Siga estos pasos para definir métodos para mostrar correctamente la pantalla de presentación extendida.

  1. Agregar espacios de nombres necesarios

    Deberá agregar los siguientes espacios de nombres a ExtendedSplash.xaml.cs para acceder a la clase SplashScreen, la estructura Rect y los eventos Window.SizeChanged.

    using Windows.ApplicationModel.Activation;
    using Windows.Foundation;
    using Windows.UI.Core;
    
  2. Crear una clase parcial y declarar variables de clase

    Incluya el código siguiente en ExtendedSplash.xaml.cs para crear una clase parcial para representar una pantalla de presentación extendida.

    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
    }
    

    Estas variables de clase son usadas por varios métodos. La variable splashImageRect almacena las coordenadas en las que el sistema muestra la imagen de la pantalla de presentación de la aplicación. La variable splash almacena un objeto SplashScreen y la variable dismissed realiza un seguimiento de si el sistema ha descartado o no la pantalla de presentación que muestra el sistema.

  3. Definir un constructor para la clase que coloca correctamente la imagen

    El código siguiente define un constructor para la clase de pantalla de presentación extendida que escucha eventos de cambio de tamaño de ventana, coloca la imagen y (opcional) control de progreso en la pantalla de presentación extendida, crea un marco para la navegación y llama a un método asincrónico para restaurar un estado de sesión guardado.

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

    Asegúrese de registrar el controlador de Window.SizeChanged (ExtendedSplash_OnResize en el ejemplo) en el constructor de clase para que la aplicación coloque la imagen correctamente en la pantalla de presentación extendida.

  4. Definir un método de clase para colocar la imagen en la pantalla de presentación extendida

    Este código muestra cómo colocar la imagen en la página de presentación extendida con la variable de clase splashImageRect.

    void PositionImage()
    {
        extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
        extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
        extendedSplashImage.Height = splashImageRect.Height;
        extendedSplashImage.Width = splashImageRect.Width;
    }
    
  5. (Opcional) Define un método de clase para colocar un control de progreso en la pantalla de presentación extendida

    Si decide agregar una ProgressRing a la pantalla de presentación extendida, colóquela en relación con la imagen de la pantalla de presentación. Agregue el código siguiente a ExtendedSplash.xaml.cs para centrar el ProgressRing 32 píxeles debajo de la imagen.

    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 de la clase , defina un controlador para el evento Dismissed

    En ExtendedSplash.xaml.cs, responda cuando se produzca el evento SplashScreen.Dismissed estableciendo la variable de clase dismissed en true. Si la aplicación tiene operaciones de configuración, agréguelas a este controlador 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...
    }
    

    Una vez completada la configuración de la aplicación, desplácese fuera de la pantalla de presentación extendida. El código siguiente define un método denominado DismissExtendedSplash que navega hasta el MainPage definido en el archivo MainPage.xaml de la aplicación.

    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 de la clase , defina un controlador para eventos Window.SizeChanged

    Prepare la pantalla de presentación extendida para cambiar la posición de sus elementos si un usuario cambia el tamaño de la ventana. Este código responde cuando se produce un evento Window.SizeChanged capturando las nuevas coordenadas y reposicionando la imagen. Si ha agregado un control de progreso a la pantalla de presentación extendida, reposicione también dentro de este controlador de eventos.

    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:

     Antes de intentar obtener la ubicación de la imagen, asegúrese de que la variable de clase (splash) contiene un objeto SplashScreen válido, como se muestra en el ejemplo.

     

  8. (opcional) Agregar un método de clase para restaurar un estado de sesión guardado

    El código que agregó al método OnLaunched en el paso 4: Modificar el controlador de activación de inicio hace que la aplicación muestre una pantalla de presentación extendida cuando se inicia. Para consolidar todos los métodos relacionados con el inicio de la aplicación en la clase de pantalla de presentación extendida, podría considerar la posibilidad de agregar un método al archivo ExtendedSplash.xaml.cs para restaurar el estado de la aplicación.

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

    Al modificar el controlador de activación de inicio en App.xaml.cs, también establecerá loadstate en true si el anterior ApplicationExecutionState de la aplicación era Terminated. Si es así, el método RestoreState restaura la aplicación a su estado anterior. Para obtener información general sobre el inicio, la suspensión y la finalización de la aplicación, consulte ciclo de vida de la aplicación.

Modificación del controlador de activación de inicio

Cuando se inicia la aplicación, el sistema pasa información de la pantalla de presentación al controlador de eventos de activación de inicio de la aplicación. Puede usar esta información para colocar correctamente la imagen en la página de presentación extendida. Puedes obtener esta información de la pantalla de presentación de los argumentos del evento de activación que se pasan al manejador de OnLaunched de la aplicación (consulta la variable args en el código siguiente).

Si aún no has invalidado el controlador de OnLaunched para tu aplicación, consulta Ciclo de vida de la aplicación para obtener información sobre cómo controlar los eventos de activación.

En App.xaml.cs, agregue el código siguiente para crear y mostrar una pantalla de presentación extendida.

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

El código siguiente difiere ligeramente de los fragmentos de código que se muestran en los pasos anteriores.

  • ExtendedSplash.xaml incluye un botón DismissSplash. Cuando se hace clic en este botón, un controlador de eventos, DismissSplashButton_Click, llama al método DismissExtendedSplash. En la aplicación, llame a DismissExtendedSplash cuando la aplicación haya terminado de cargar recursos o inicializar su interfaz de usuario.
  • Esta aplicación también utiliza una plantilla de proyecto UWP, que emplea navegación con marco . Como resultado, en App.xaml.cs, el controlador de activación de inicio (OnLaunched) define un rootFrame y lo usa para establecer el contenido de la ventana de la aplicación.

ExtendedSplash.xaml

En este ejemplo se incluye un botón DismissSplash porque no tiene recursos de aplicación para cargar. En la aplicación, descarte automáticamente la pantalla de presentación extendida cuando la aplicación haya terminado de cargar recursos o preparar su interfaz de usuario 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

Tenga en cuenta que el método DismissExtendedSplash se llama desde el controlador de eventos de clic para el botón DismissSplash. En la aplicación, no necesitarás un botón DismissSplash. En su lugar, llame a DismissExtendedSplash cuando la aplicación haya terminado de cargar recursos y quiera navegar a su 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

Este proyecto se creó utilizando la plantilla de proyecto Aplicación Vacía (XAML) para UWP en Visual Studio. Los controladores de eventos OnNavigationFailed y OnSuspending se generan automáticamente y no es necesario cambiar para implementar una pantalla de presentación extendida. Este tema solo modifica OnLaunched.

Si no utilizaste una plantilla de proyecto para tu aplicación, consulta el paso 4: Modificar el controlador de activación de inicio para un ejemplo de un OnLaunched modificado que no utiliza la navegación con 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();
        }
    }
}

Referencia