スプラッシュ スクリーンの表示時間の延長
アプリに追加スプラッシュ画面を作成すれば、より長い時間、スプラッシュ画面を表示することができます。 この拡張画面は、アプリの起動時に表示されるスプラッシュ画面を模倣しますが、カスタマイズできます。 リアルタイムの読み込み情報を表示する場合でも、アプリで初期 UI を準備する時間を追加する場合でも、拡張スプラッシュ画面を使用して起動エクスペリエンスを定義できます。
Note
このトピックで "追加スプラッシュ画面" という用語は、表示される時間が延長されたスプラッシュ画面を指します。 これは、 SplashScreen クラスから派生するサブクラスを意味するものではありません。
重要な API
このトピックでは、次の API を使用します。
既定のスプラッシュ画面の推奨事項
次の推奨事項に従って、拡張スプラッシュ画面が既定のスプラッシュ画面を正確に模倣していることを確認します。
- 拡張スプラッシュ画面ページでは、アプリ マニフェストでスプラッシュ画面に指定されたイメージ (アプリのスプラッシュ画面イメージ) と一致する 620 x 300 ピクセルの画像を使用する必要があります。 Microsoft Visual Studio では、スプラッシュスクリーンの設定は、アプリ マニフェスト (Package.appxmanifest ファイル) の Visual Assets タブの Splash Screen セクションに格納されます。
- 拡張スプラッシュ画面では、アプリ マニフェストでスプラッシュ画面に指定された背景色 (アプリのスプラッシュ画面の背景) と一致する背景色を使用する必要があります。
- コードでは、 SplashScreen クラスを使用して、アプリのスプラッシュ画面イメージを既定のスプラッシュ画面と同じ画面座標に配置する必要があります。
- コードは、 SplashScreen クラスを使用して拡張スプラッシュ画面上の項目の位置を変更することで、ウィンドウのサイズ変更イベント (画面が回転したときや、アプリが画面上の別のアプリの横に移動されたときなど) に応答する必要があります。
次の手順を使用して、既定のスプラッシュスクリーンを効果的に模倣する拡張スプラッシュスクリーンを作成します。
既存のアプリに Blank Page 項目を追加する
このトピックでは、C#、Visual Basic、または C++ を使用して、既存の ユニバーサル Windows プラットフォーム (UWP) アプリ プロジェクトに拡張スプラッシュスクリーンを追加することを前提としています。
- Visual Studio でアプリを開きます。
- メニュー バーから Project を押すか開き、[新しい項目 追加] をクリック。 [新しい項目の追加] ダイアログ ボックスが表示されます。
- このダイアログ ボックスから、新しい Blank Page をアプリに追加します。 このトピックでは、拡張スプラッシュ画面のページに "ExtendedSplash" という名前を付けます。
Blank Page 項目を追加すると、マークアップ用 (ExtendedSplash.xaml) 用とコード用 (ExtendedSplash.xaml.cs) の 2 つのファイルが生成されます。
拡張スプラッシュ画面用の基本的な XAML
拡張スプラッシュ画面に画像と進行状況コントロールを追加するには、次の手順に従います。
ExtendedSplash.xaml ファイル内:
- 既定の Grid 要素の Background プロパティを、アプリ マニフェスト (Package.appxmanifest ファイルの Visual Assets セクション) でアプリのスプラッシュ画面に設定した背景色と一致するように変更します。 既定のスプラッシュ画面の色は薄い灰色 (16 進数 #464646) です。 この Grid 要素は、新しい Blank Page を作成するときに既定で提供されることに注意してください。 Gridを使用する必要はありません。これは、拡張スプラッシュスクリーンを構築するための便利なベースにすぎません。
- Grid に Canvas 要素を追加します。 この 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>
Note
この例では、ProgressRing の幅を 20 ピクセルに設定しています。 手動で幅をアプリで動作する値に設定できますが、コントロールは 20 ピクセル未満の幅ではレンダリングされません。
拡張スプラッシュ スクリーン クラスの重要なコード
拡張スプラッシュ画面は、ウィンドウ サイズ (Windows のみ) または向きが変化するたびに応答する必要があります。 使用するイメージの位置を更新して、ウィンドウの変更に関係なく拡張スプラッシュ画面が適切に表示されるようにする必要があります。
拡張スプラッシュ画面を正しく表示するメソッドを定義するには、次の手順を使用します。
必要な名前空間を追加する
SplashScreen クラス、Rect 構造体、および Window.SizeChanged イベントにアクセスするには、ExtendedSplash.xaml.cs に次の名前空間を追加する必要があります。
using Windows.ApplicationModel.Activation; using Windows.Foundation; using Windows.UI.Core;
部分クラスを作成し、クラス変数を宣言する
拡張スプラッシュ画面を表す部分クラスを作成するには、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に追加して、 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)); }
クラス内で、Dismissed イベントのハンドラーを定義します。
ExtendedSplash.xaml.csで、
dismissed
クラス変数を true に設定して、SplashScreen.Dismissed イベントが発生したときに応答します。 アプリにセットアップ操作がある場合は、このイベント ハンドラーに追加します。// 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 ファイルで定義されている
MainPage
に移動するDismissExtendedSplash
というメソッドを定義します。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(); } }
Note
画像の場所を取得する前に、クラス変数 (
splash
) に有効な SplashScreen オブジェクトが含まれていることを確認してください (例を参照)。(省略可能)保存されたセッション状態を復元するクラス メソッドを追加する
手順 4: 起動アクティブ化ハンドラーを変更するOnLaunched メソッドに追加したコードにより起動時にアプリに拡張スプラッシュ画面が表示されます。 追加スプラッシュ画面クラスにアプリの起動に関連するすべてのメソッドを統合するには、ExtendedSplash.xaml.cs ファイルに、アプリの状態を復元するメソッドを追加することを検討します。
void RestoreState(bool loadState) { if (loadState) { // code to load your app's state here } }
App.xaml.csで起動アクティブ化ハンドラーを変更するときに、アプリの前の ApplicationExecutionState がTerminatedされた場合も、
loadstate
を true に設定します。 その場合、RestoreState
メソッドはアプリを以前の状態に復元します。 アプリの起動、中断、終了の概要については、「 App ライフサイクル」を参照してください。
起動アクティブ化ハンドラーを変更する
アプリが起動されると、システムはスプラッシュ画面情報をアプリの起動アクティブ化イベント ハンドラーに渡します。 この情報を使用して、拡張スプラッシュ画面ページに画像を正しく配置できます。 このスプラッシュ画面情報は、アプリの OnLaunched ハンドラーに渡されるアクティブ化イベント引数から取得できます (次のコードの args
変数を参照してください)。
アプリの OnLaunched ハンドラーをまだオーバーライドしていない場合は、「 App ライフサイクル アクティブ化イベントを処理する方法」を参照してください。
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
を呼び出します。 - このアプリでは、 Frame ナビゲーションを使用する 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
このプロジェクトは、UWP アプリの [新しいアプリケーション (XAML)] プロジェクト テンプレートを使用して Visual Studio で作成されました。 OnNavigationFailed
とOnSuspending
の両方のイベント ハンドラーが自動的に生成され、拡張スプラッシュスクリーンを実装するために変更する必要はありません。 このトピックでは、 OnLaunched
のみを変更します。
アプリにプロジェクト テンプレートを使用していない場合は、「手順 4: 起動アクティブ化ハンドラーを変更するFrameナビゲーションを使用しない変更された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();
}
}
}
関連トピック
リファレンス