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


Более продолжительное отображение экрана-заставки

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

Примечание.

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

Важные API

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

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

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

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

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

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

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

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

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

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

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

В файле ExtendedSplash.xaml:

  • Измените свойство Background элемента Grid по умолчанию, чтобы он соответствовал цвету фона, заданному для экрана-заставки приложения в манифесте приложения (в разделе "Визуальные ресурсы" файла Package.appxmanifest). Цвет экрана-заставки по умолчанию — светло-серый (шестнадцатеричное значение #464646). Обратите внимание, что этот элемент Grid предоставляется по умолчанию при создании новой пустой страницы. Вам не нужно использовать сетку. Это просто удобная база для создания расширенного экрана-заставки.
  • Добавьте элемент Canvas в Grid. Этот холст будет использоваться для размещения изображения расширенного экрана-заставки.
  • Добавьте элемент 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. Добавление обязательных пространств имен

    Чтобы получить доступ к классу SplashScreen, структуре Rect и события Window.SizeChanged, необходимо добавить следующие пространства имен, чтобы 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, который использует навигацию кадров . В результате в 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 (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();
        }
    }
}

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