本文采用WindowsPhone 8 SDK,vs 2013,此方法同樣适用于wp7,wp8.1.
一般的wp8應用程式在建立時,項目目錄中會預設提供一張在程式啟動時顯示的一張圖檔,名字叫SplashScreenImage.jpg。這是因為在程式啟動時可能會耗費一定的時間來加載首界面,這時這張圖檔就會先出現。如果你要改變啟動畫面,使用自己定義好的另外的圖檔替換它就可以。但是如果,要在啟動畫面上顯示動态的效果呢?下面就來說一下。
為了要在程式啟動時顯示動态界面,就要将一個頁面在MainPage之前顯示。也就是說,要把之前的預設的啟動畫面去掉。為了實作這個效果,需要先把SplashScreenImage.jpg删除掉。建立一個UserControl來顯示動态效果,在MianPage顯示之前,先顯示該UserControl.同時控制其顯示的時間,這個時間我們也是可以控制的。這裡還要用到BackgroundWorker線程。
使用BackgroundWorker類,你在一個單獨的背景線程進行操作,而讓wp的渲染線程和UI線程繼續執行不受影響。當線程中的事務處理完後可以回報到ui線程上。
注意:在DoWork事件處理函數中不要操作任何使用者界面對象。當然ProgressChanged和RunWorkerCompleted事件回調函數中,你能操作使用者界面。具體的使用在後面的代碼中,有詳細說明。
首先,建立一個UserControl,如下圖:
添加建立項
建立好了之後,要将其寬高改為height =800 ,weight = 480,不然覆寫不了整個螢幕。
下面是該control的xmal的代碼,代碼中有注釋。
<UserControl x:Class="LoadingPage.LoadingControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="800" d:DesignWidth="480"> <!--設定寬高-->
<!--控件動畫資源定義-->
<UserControl.Resources>
<!--使用故事闆-->
<Storyboard x:Key="LoadAnimation">
<DoubleAnimation From="0" To="359" Duration="0:0:1" RepeatBehavior="Forever"
Storyboard.TargetName="VisualTransform"
Storyboard.TargetProperty="Angle"/>
</Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneAccentBrush}">
<!--使用 * 可以平均配置設定布局-->
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="正在加載,請稍後。。。" Grid.Row="1" VerticalAlignment="Center"
HorizontalAlignment="Center"/>
<!-- grid裡,使用path畫一個圈,而動畫以該grid為機關-->
<Grid x:Name="Visual" Margin="0,30,0,0" RenderTransformOrigin="0.5,0.5" Grid.Row="2"
VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="VisualTransform"/>
</TransformGroup>
</Grid.RenderTransform>
<Path Width="50" Height="50" Stretch="Fill"
StrokeThickness="5"
StrokeStartLineCap="Round" Data="M1,0 A1,2,90,1,1,0,0">
<Path.Stroke>
<LinearGradientBrush StartPoint="1,0.8" EndPoint="0.3,0.1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Path.Stroke>
</Path>
</Grid>
</Grid>
</UserControl>
其cs 代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Windows.Media.Animation;
namespace LoadingPage
{
public partial class LoadingControl : UserControl
{
public LoadingControl()
{
InitializeComponent();
//設定根grid布局寬高為實際裝置螢幕的寬高
LayoutRoot.Height = App.Current.Host.Content.ActualHeight;
LayoutRoot.Width = App.Current.Host.Content.ActualWidth;
//在loaded和unloaded時,添加路由事件,開始和停止動畫
this.Loaded += new RoutedEventHandler(LoadingScreenControl_Loaded);
this.Unloaded += new RoutedEventHandler(LoadingScreenControl_Unloaded);
}
void LoadingScreenControl_Unloaded(object sender, RoutedEventArgs e)
{
//加載動畫資源
Storyboard sb = this.Resources["LoadAnimation"] as Storyboard;
//停止動畫
sb.Stop();
}
void LoadingScreenControl_Loaded(object sender, RoutedEventArgs e)
{
//加載動畫資源
Storyboard sb = this.Resources["LoadAnimation"] as Storyboard;
//開始動畫
sb.Begin();
}
}
}
接下來,将要在MainPage中加入要處理的代碼
1、添加以下命名空間,在MainPage.xaml.cs檔案中:
using System.Threading;
using System.Windows.Controls.Primitives;
2、使用Popup類,将UserControl添加到Popup中,使其顯示。
3、使用BackgroundWorker,進行計時(也可以做其他的初始化操作),讓開始界面顯示一定時間。
4、結束,取消顯示popup
下面是MainPage.xaml.cs代碼
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using LoadingPage.Resources;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Threading;
namespace LoadingPage
{
public partial class MainPage : PhoneApplicationPage
{
// 構造函數
public MainPage()
{
InitializeComponent();
//在首頁初始化後調用動态加載界面
LoadWelcomePage();
// 用于本地化 ApplicationBar 的示例代碼
//BuildLocalizedApplicationBar();
}
void LoadWelcomePage(int time)
{
//使用popup,将使用者控件LoadingControl作為其孩子
Popup popup = new Popup();
LoadingControl loadingcontrol = new LoadingControl();
popup.Child = loadingcontrol;
popup.IsOpen = true;//設定為true 才會顯示
//建立背景線程
BackgroundWorker bkw = new BackgroundWorker();
//需要在背景線程中做的工作,注意不能操作與UI線程相關内容
bkw.DoWork += ( (s,e) =>
{
Thread.Sleep(time);
});
//背景線程工作執行完後所要做的事情
bkw.RunWorkerCompleted += ( (s,e) =>
{
this.Dispatcher.BeginInvoke(() =>
{
popup.IsOpen = false
});
});
//執行背景線程
bkw.RunWorkerAsync();
}
// 用于生成本地化 ApplicationBar 的示例代碼
//private void BuildLocalizedApplicationBar()
//{
// // 将頁面的 ApplicationBar 設定為 ApplicationBar 的新執行個體。
// ApplicationBar = new ApplicationBar();
// // 建立新按鈕并将文本值設定為 AppResources 中的本地化字元串。
// ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
// appBarButton.Text = AppResources.AppBarButtonText;
// ApplicationBar.Buttons.Add(appBarButton);
// // 使用 AppResources 中的本地化字元串建立新菜單項。
// ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
// ApplicationBar.MenuItems.Add(appBarMenuItem);
//}
}
}
Thread.Sleep()方法在using System.Threading;命名空間中
BackgroundWorker在using System.Windows.Controls.Primitives;命名空間中
最後
如果不使用popup和usercontrol,而建立一個新的page,設定其為首頁,是不是也可以。但是這樣就會被頁面堆棧記錄,當進行傳回操作時,就會傳回到該也頁面上來,就失去了起意義了。當然也可以管理頁面堆棧,删除其記錄,但是這樣,就顯得麻煩了。。
源碼在這裡