앱에 대한 확장된 시작 화면을 만들어 더 많은 시간 동안 시작 화면을 표시합니다. 이 확장된 화면은 앱이 시작될 때 표시되는 시작 화면을 모방하지만 사용자 지정할 수 있습니다. 실시간 로드 정보를 표시하거나 앱에 초기 UI를 준비하는 데 추가 시간을 주려는 경우 확장된 시작 화면을 통해 시작 환경을 정의할 수 있습니다.
비고
이 항목의 "확장된 시작 화면"이라는 문구는 오랜 시간 동안 화면에 유지되는 시작 화면을 나타냅니다. SplashScreen 클래스에서 파생되는 하위 클래스를 의미하지는 않습니다.
중요 API
이 항목에서는 다음 API가 사용됩니다.
- SplashScreen 클래스
- Window.SizeChanged 이벤트
- application.OnLaunched 메서드
기본 시작 화면 권장 사항
다음 권장 사항에 따라 확장된 시작 화면이 기본 시작 화면을 정확하게 모방하는지 확인합니다.
- 확장된 시작 화면 페이지는 앱 매니페스트(앱의 시작 화면 이미지)에서 시작 화면에 지정된 이미지와 일치하는 620 x 300 픽셀 이미지를 사용해야 합니다. Microsoft Visual Studio에서 시작 화면 설정은 앱 매니페스트(Package.appxmanifest 파일)의 Visual Assets 탭의 시작 화면 섹션에 저장됩니다.
- 확장된 시작 화면은 앱 매니페스트(앱의 시작 화면 배경)에서 시작 화면에 지정된 배경색과 일치하는 배경색을 사용해야 합니다.
- 코드는 SplashScreen 클래스를 사용하여 앱의 시작 화면 이미지를 기본 시작 화면과 동일한 화면 좌표에 배치해야 합니다.
- 코드는 SplashScreen 클래스를 사용하여 확장된 시작 화면에서 항목의 위치를 변경하여 창 크기 조정 이벤트(예: 화면이 회전되거나 앱이 다른 앱 옆에 이동하는 경우)에 응답해야 합니다.
다음 단계를 사용하여 기본 시작 화면을 효과적으로 모방하는 확장된 시작 화면을 만듭니다.
기존 앱에 빈 페이지 항목 추가
이 항목에서는 C#, Visual Basic 또는 C++를 사용하여 기존 UWP(유니버설 Windows 플랫폼) 앱 프로젝트에 확장된 시작 화면을 추가하려는 경우를 가정합니다.
- Visual Studio에서 앱을 엽니다.
- 메뉴 모음에서 Project를 눌러 열고 새 항목 추가를 클릭합니다. 새 항목 추가 대화 상자가 나타납니다.
- 이 대화 상자에서 새 빈 페이지를 앱에 추가하세요. 이 항목에서는 확장된 시작 화면 페이지의 이름을 "ExtendedSplash"로 지정합니다.
빈 페이지 항목을 추가하면 마크업을 위한 파일(ExtendedSplash.xaml)과 코드를 위한 파일(ExtendedSplash.xaml.cs) 두 개가 생성됩니다.
확장된 스플래시 화면의 필수 XAML
확장 시작 화면에 이미지 및 진행률 컨트롤을 추가하려면 다음 단계를 수행합니다.
ExtendedSplash.xaml 파일에서:
- Package.appxmanifest 파일의 Visual Assets 섹션에 있는 앱 매니페스트에서 앱 시작 화면에 대해 설정한 배경색과 일치하도록 기본 Grid 요소의 Background 속성을 변경합니다. 기본 시작 화면 색은 연한 회색(16진수 값 #464646)입니다. 이 Grid 요소는 새 빈 페이지를 만들 때 기본적으로 제공됩니다. 그리드를 사용할 필요가 없습니다 . 확장된 시작 화면을 빌드하기 위한 편리한 기반일 뿐입니다.
- Canvas 요소를 Grid에 추가합니다. 이 Canvas을 사용하여 확장된 시작 화면 이미지를 배치할 것입니다.
- Image 요소를 Canvas에 추가합니다. 기본 스플래시 화면에 대해 선택한 620 x 300 픽셀 이미지를 확장된 스플래시 화면에도 동일하게 사용하십시오.
- (선택 사항) 진행률 컨트롤을 추가하여 앱이 로드되고 있음을 사용자에게 표시합니다. 이 항목에서는 확정되거나 확정되지 않은 ProgressBar대신 ProgressRing추가합니다.
다음 예제에서는 이러한 추가 및 변경 내용이 포함된 Grid 를 보여 줍니다.
<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에만 해당) 또는 방향이 변경 될 때마다 응답해야 합니다. 창이 어떻게 변경되더라도 확장된 시작 화면이 멋지게 보이도록 사용하는 이미지의 위치를 업데이트해야 합니다.
다음 단계를 사용하여 확장된 시작 화면을 올바르게 표시하는 메서드를 정의합니다.
필수 네임스페이스 추가
SplashScreen 클래스, Rect 구조체 및 Window.SizeChanged 이벤트에 액세스하려면 ExtendedSplash.xaml.cs 다음 네임스페이스를 추가해야 합니다.
using Windows.ApplicationModel.Activation; using Windows.Foundation; using Windows.UI.Core;
partial 클래스를 만들고 클래스 변수를 선언합니다.
확장된 시작 화면을 나타내는 부분 클래스를 만들려면 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
, 변수는 시스템에서 표시하는 시작 화면이 해제되었는지 여부를 추적합니다.클래스에 이미지가 올바르게 위치하도록 생성자를 정의합니다.
다음 코드는 창 크기 조정 이벤트를 수신 대기하고, 확장된 시작 화면에 이미지 및(선택 사항) 진행률 컨트롤을 배치하고, 탐색 프레임을 만들고, 저장된 세션 상태를 복원하는 비동기 메서드를 호출하는 확장 시작 화면 클래스에 대한 생성자를 정의합니다.
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
예제 참조)를 등록하세요.확장된 시작 화면에 이미지를 배치하는 클래스 메서드 정의
이 코드는 클래스 변수를 사용하여 확장된 시작 화면 페이지에 이미지를 배치하는
splashImageRect
방법을 보여 줍니다.void PositionImage() { extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X); extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y); extendedSplashImage.Height = splashImageRect.Height; extendedSplashImage.Width = splashImageRect.Width; }
(선택 사항) 확장된 시작 화면에 진행률 컨트롤을 배치할 클래스 메서드를 정의합니다.
확장된 시작 화면에 ProgressRing을 추가하도록 선택한 경우, 시작 화면 이미지를 기준으로 배치하십시오. ExtendedSplash.xaml.cs에 다음 코드를 추가하여 이미지를 기준으로 32픽셀 아래에 ProgressRing을 중앙에 배치합니다.
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)); }
클래스 내에서 Dismissed 이벤트에 대한 처리기를 정의합니다.
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... }
앱 설정이 완료되면 확장된 시작 화면을 벗어나십시오. 다음 코드는 앱의 MainPage.xaml 파일에 정의된
DismissExtendedSplash
로 이동하는MainPage
메서드를 정의합니다.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; }); }
클래스 내에서 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 개체가 포함되어 있는지 확인합니다.(선택 사항) 저장된 세션 상태를 복원하는 클래스 메서드 추가
4단계: 시작 활성화 처리기 수정에서 OnLaunched 메서드에 추가한 코드로 인해, 앱이 시작될 때 확장된 시작 화면이 표시됩니다. 확장된 시작 화면 클래스에서 앱 시작과 관련된 모든 메서드를 통합하려면 ExtendedSplash.xaml.cs 파일에 메서드를 추가하여 앱의 상태를 복원하는 것이 좋습니다.
void RestoreState(bool loadState) { if (loadState) { // code to load your app's state here } }
App.xaml.cs에서 시작 활성화 처리기를 수정할 때, 앱의 이전
loadstate
가 Terminated상태였다면 을 true로 설정합니다. 이 경우 메서드는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
. 앱에서 리소스 로드 또는 UI 초기화가 완료되면 호출DismissExtendedSplash
합니다. - 이 앱은 프레임 탐색을 사용하는 UWP 앱 프로젝트 템플릿도 사용합니다. 따라서 App.xaml.cs에서 시작 활성화 처리기(OnLaunched)는 하나의
rootFrame
를 정의하고 이를 사용하여 앱 창의 콘텐츠를 설정합니다.
ExtendedSplash.xaml
이 예제에는 로드할 앱 리소스가 없으므로 DismissSplash
버튼이 포함되어 있습니다. 앱에서 리소스 로드 또는 초기 UI 준비 작업이 완료되면 확장된 시작 화면을 자동으로 해제합니다.
<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
이 프로젝트는 Visual Studio에서 UWP 빈 앱 (XAML) 프로젝트 템플릿을 사용하여 만들어졌습니다.
OnNavigationFailed
OnSuspending
이벤트 처리기와 이벤트 처리기는 모두 자동으로 생성되며 확장된 시작 화면을 구현하기 위해 변경할 필요가 없습니다. 이 항목에서는 OnLaunched
만 수정합니다.
앱에 프로젝트 템플릿을 사용하지 않은 경우 프레임 탐색을 사용하지 않는 수정된 OnLaunched
예제는 4단계: 시작 활성화 처리기 수정을 참조하세요.
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();
}
}
}
관련 항목
참조
- Windows.ApplicationModel.Activation 네임스페이스
- Windows.ApplicationModel.Activation.SplashScreen 클래스
- Windows.ApplicationModel.Activation.SplashScreen.ImageLocation 프로퍼티 속성
- Windows.ApplicationModel.Core.CoreApplicationView.Activated 이벤트