Поделиться через


Продлите время отображения экрана-заставки

Увеличьте время отображения экрана-заставки, создав расширенную экран-заставку для вашего приложения. Этот расширенный экран имитирует экран-заставку, показанный при запуске приложения, но его можно настроить. Хотите ли вы отображать сведения о загрузке в режиме реального времени или просто предоставить приложению дополнительное время для подготовки исходного пользовательского интерфейса, расширенный экран-заставка позволяет определить возможности запуска.

Замечание

Фраза "расширенный экран-заставка" в этом разделе относится к экрану-заставке, который остается на экране в течение длительного периода времени. Это не означает подкласс, производный от класса SplashScreen.

Важные API

В этом разделе используются следующие API:

Рекомендации по экрану заставки по умолчанию

Убедитесь, что расширенный экран-заставка точно имитирует экран заставки по умолчанию, выполнив следующие рекомендации:

  • Страница расширенного экрана-заставки должна использовать изображение с заставкой 620 x 300 пикселей, которое соответствует изображению, указанному для экрана-заставки в манифесте приложения (изображение экрана-заставки приложения). В Microsoft Visual Studio настройки экрана приветствия хранятся в разделе Экран приветствия на вкладке Визуальные ресурсы в манифесте приложения (файл Package.appxmanifest).
  • Расширенный экран-заставка должен использовать цвет фона, соответствующий цвету фона, указанному для экрана-заставки в манифесте приложения (фон экрана-заставки приложения).
  • Код должен использовать класс SplashScreen, чтобы разместить изображение экрана-заставки приложения в той же координате экрана, что и экран заставки по умолчанию.
  • Код должен реагировать на события изменения размера окна (например, когда экран поворачивается или приложение перемещается рядом с другим приложением на экране) с помощью класса SplashScreen для изменения положения элементов на расширенном экране-заставки.

Выполните следующие действия, чтобы создать расширенный экран-заставку, который эффективно имитирует экран заставки по умолчанию.

Добавьте элемент пустой страницы в существующее приложение

В этом разделе предполагается, что вы хотите добавить расширенный экран-заставку в существующий проект приложения универсальной платформы Windows (UWP) с помощью C#, Visual Basic или C++.

  • Откройте приложение в Visual Studio.
  • Нажмите или откройте Project в строке меню и нажмите Добавить новый элемент. Появится диалоговое окно Добавить новый элемент.
  • В этом диалоговом окне добавьте в приложение новую пустую страницу . В этом разделе страницу расширенного экрана-заставки называют "ExtendedSplash".

Добавление элемента пустой страницы создает два файла, один для разметки (ExtendedSplash.xaml) и другой для кода (ExtendedSplash.xaml.cs).

Основные XAML для расширенного экрана-заставки

Выполните следующие действия, чтобы добавить изображение и индикатор выполнения на заставку расширенного экрана.

В файле ExtendedSplash.xaml:

  • Измените свойство Background элемента по умолчанию Grid так, чтобы оно соответствовало цвету фона, который вы установили для экрана приветствия вашего приложения в манифесте приложения (в разделе Визуальные ресурсы файла Package.appxmanifest). Цвет экрана-заставки по умолчанию — светло-серый (шестнадцатеричное значение #464646). Обратите внимание, что элемент сетки предоставляется по умолчанию при создании новой пустой страницы. Вам не нужно использовать сетка , поскольку она всего лишь удобной основой для создания расширенного экрана-заставки.
  • Добавьте элемент Canvas в Grid. Вы будете использовать этот Canvas для размещения расширенного изображения экрана-заставки.
  • Добавьте элемент Image в Canvas. Используйте то же изображение 620 x 300 пикселей для расширенного сплэш-экрана, которое вы выбрали для экрана сплэш по умолчанию.
  • (Необязательно) Добавьте элемент управления хода выполнения, чтобы показать пользователям, что приложение загружается. В этом разделе добавляется ProgressRingвместо определенного или неопределенного ProgressBar.

В следующем примере показана сетка с этими дополнениями и изменениями.

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

Замечание

В этом примере ширина ProgressRing составляет 20 пикселей. Вы можете вручную задать ее ширину значением, которое работает для приложения, однако элемент управления не будет отображаться на ширине менее 20 пикселей.

Основной код для расширенного класса заставки

Расширенный экран-заставка должен реагировать всякий раз, когда размер окна (только Для Windows) или ориентация изменяется. Позиция используемого изображения должна быть обновлена таким образом, чтобы расширенный экран-заставка выглядел хорошо независимо от того, как изменяется окно.

Используйте эти действия, чтобы определить методы для правильного отображения расширенного экрана-заставки.

  1. Добавьте необходимые пространства имен

    Чтобы добавить следующие пространства имен в ExtendedSplash.xaml.cs для получения доступа к классу SplashScreen, структуре Rect и событиям Window.SizeChanged.

    using Windows.ApplicationModel.Activation;
    using Windows.Foundation;
    using Windows.UI.Core;
    
  2. Создание частичного класса и объявление переменных классов

    Добавьте следующий код в ExtendedSplash.xaml.cs, чтобы создать частичный класс для представления расширенного экрана-заставки.

    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
    }
    

    Эти переменные класса используются несколькими методами. Переменная splashImageRect сохраняет координаты, в которых система отображала изображение экрана-заставки для приложения. Переменная splash хранит объект SplashScreen, а переменная dismissed отслеживает, был ли экран-заставка, который отображает система, уже закрыт.

  3. Определите конструктор для класса, который правильно размещает изображение

    Следующий код определяет конструктор для класса расширенного экрана-заставки, который прослушивает события изменения размера окна, позиционирует изображение и (необязательно) индикатор выполнения на расширенном экране-заставке, создает навигационную рамку и вызывает асинхронный метод для восстановления сохраненного состояния сеанса.

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

    Обязательно зарегистрируйте обработчик Window.SizeChanged (ExtendedSplash_OnResize в примере) в конструкторе классов, чтобы приложение правильно позиционировало изображение на расширенном экране-заставке.

  4. Определите метод класса для позиционирования изображения на расширенном экране приветствия

    В этом коде показано, как разместить изображение на странице расширенного экрана-заставки с помощью переменной класса splashImageRect.

    void PositionImage()
    {
        extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
        extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
        extendedSplashImage.Height = splashImageRect.Height;
        extendedSplashImage.Width = splashImageRect.Width;
    }
    
  5. (необязательно) Определите метод класса для размещения элемента управления прогрессом на экране расширенной заставки

    Если вы решили добавить ProgressRing на расширенный экран-заставку, поместите его относительно изображения экрана-заставки. Добавьте следующий код в ExtendedSplash.xaml.cs, чтобы разместить ProgressRing на 32 пикселя ниже изображения.

    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. Внутри класса определите обработчик для события "Отклонено"

    В ExtendedSplash.xaml.cs ответьте на событие SplashScreen.Dismissed, установив переменной класса dismissed значение true. Если у приложения есть операции установки, добавьте их в этот обработчик событий.

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

    После завершения настройки приложения перейдите с расширенного заставочного экрана. Следующий код определяет метод с именем DismissExtendedSplash, который переходит к MainPage, определенному в файле MainPage.xaml приложения.

    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. Внутри класса определите обработчик событий Window.SizeChanged

    Подготовьте расширенный экран-заставку, чтобы изменить положение его элементов, если пользователь изменяет размер окна. Этот код реагирует на событие Window.SizeChanged путем записи новых координат и изменения положения изображения. Если вы добавили элемент управления хода выполнения на расширенный экран-заставку, переместите его внутри этого обработчика событий.

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

    Замечание

     Прежде чем попытаться получить расположение изображения, убедитесь, что переменная класса (splash) содержит допустимый объект SplashScreen, как показано в примере.

     

  8. (необязательно) Добавьте метод класса для восстановления сохраненного состояния сеанса

    Код, добавленный в метод OnLaunched на шаге 4. Изменение обработчика активации запуска приводит к отображению приложения расширенного экрана-заставки при запуске. Чтобы объединить все методы, связанные с запуском приложения, в вашем классе расширенного экрана заставки, можно добавить метод в файл ExtendedSplash.xaml.cs для восстановления состояния приложения.

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

    При изменении обработчика активации запуска в App.xaml.cs вы также установите для loadstate значение true, если предыдущий ApplicationExecutionState приложения был завершен. В этом случае метод RestoreState восстанавливает приложение до предыдущего состояния. Общие сведения о запуске, приостановке и завершении работы приложений см. в разделе жизненный цикл приложений.

Изменение обработчика активации запуска

При запуске приложения система передает сведения о экране-заставки обработчику событий активации приложения. Эти сведения можно использовать для правильного размещения изображения на странице расширенного экрана-заставки. Эти сведения об экране-заставке можно получить из аргументов события активации, передаваемых в обработчик OnLaunched приложения (см. переменную args в следующем коде).

Если вы еще не переопределили обработчик OnLaunched для приложения, обратитесь к жизненному циклу приложения, чтобы узнать, как обрабатывать события активации.

В App.xaml.cs добавьте следующий код для создания и отображения расширенного экрана-заставки.

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

Полный код

Следующий код немного отличается от фрагментов кода, показанных на предыдущих шагах.

  • ExtendedSplash.xaml содержит кнопку DismissSplash. При нажатии этой кнопки обработчик событий DismissSplashButton_Clickвызывает метод DismissExtendedSplash. В приложении вызовите DismissExtendedSplash, когда приложение выполняет загрузку ресурсов или инициализацию пользовательского интерфейса.
  • Это приложение также использует шаблон проекта приложения UWP, который использует навигацию frame. В результате в App.xaml.cs обработчик активации запуска (OnLaunched) определяет rootFrame и использует его для задания содержимого окна приложения.

ExtendedSplash.xaml

В этом примере включена кнопка DismissSplash, так как у нее нет ресурсов приложения для загрузки. В приложении автоматически закройте расширенный экран-заставку при загрузке ресурсов или подготовке исходного пользовательского интерфейса.

<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

Обратите внимание, что метод DismissExtendedSplash вызывается из обработчика событий нажатия кнопки DismissSplash. В приложении не потребуется кнопка DismissSplash. Вместо этого вызовите DismissExtendedSplash при загрузке ресурсов приложения и перейдите на главную страницу.

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

Этот проект был создан с использованием шаблона проекта приложения UWP Blank App (XAML) в Visual Studio. Обработчики событий OnNavigationFailed и OnSuspending автоматически создаются и не нужно изменять для реализации расширенного экрана-заставки. Этот раздел изменяет только OnLaunched.

Если для вашего приложения не использовался шаблон проекта, см. шаг 4: Модифицировать обработчик активации запуска, для примера измененного OnLaunched, который не использует кадровую навигацию .

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

Справочные материалы