2012年9月12日 星期三

在 Windows Phone Splash 頁面加入控制項

通常 Windows Phone 應用程式的 Splash 頁面只會顯示 SplashScreenImage.jpg
市集上有些應用程式可以在顯示圖片 1、2 秒後在同一頁跑 Progressing 動畫,
這當然也是用很硬做的方式做出來的,目前有幾套做法,

最直觀的想法就是把應用程式的起始頁做成 Splash 的樣子再加入元件,
這麼做問題是這頁會被加進導覽歷史記錄中,當用戶一直在應用程式中按 Back,
最後竟然可以回到 Splash 頁,再按 Back 才是關閉 App,很奇怪。

第二種作法是在起始頁開啟時立馬導覽到假的 Splash 頁面,
等處理完事情再用 NavigationService.GoBack() 回首頁,
但這麼做會有很大的機率看到畫面閃過一下起始頁的畫面,
或是真的 Splash 結束後黑一下才顯示假的 Splash,總之是個不安全的作法。

目前最主流的做法,還是得寫一個偽裝 Splash 的 PhoneApplicationPage,
在起始頁的建構式時利用 Popup 的方式將這個偽裝的 Splash Popup 出來,要注意幾點,
第一點,一定要在起始頁的建構式中 Popup 出這個偽裝的 Splash 頁面,
否則還是會看到起始頁的影子。
第二點,起始頁和假 Splash 的尺寸要一樣,且假 Splash 的主容器元件需寫明長寬屬性,
否則在 Popup 出來後會是一個長寬為 0 的視窗,或無法佔滿主視窗而裝得不夠像,
起始頁開啟假 Splash 的簡單範例如下

public partial class MainPage : PhoneApplicationPage
{
    private Popup mPop = null;

    public MainPage()
    {
        InitializeComponent();
        mPop = new Popup() { IsOpen = true, Child = new Splash() };
        mPop.Closed += OnPopupClosed;
    }

    private void OnPopupClosed(object sender, EventArgs e)
    {
        // 顯示 Splash 作業期間準備的資料
    }

    private void OnButtonClick(object sender, RoutedEventArgs e)
    {
        // 也可以把這頁當成一般的頁面瀏覽
        NavigationService.Navigate(new Uri("/Splash.xaml", UriKind.Relative));
    }
}

在這個範例裡我特地做了一個按鍵來導覽至假的 Splash 頁面,
因為假的 Splash 頁面也是 PhoneApplicationPage,所以當然可以被導覽過去,
如果你的應用程式流程有可能需要導覽至此假的 Splash,注意以下範例關閉事件的寫法,
此偽 Splash 必需要判斷自己的父親是不是 Popup 類別來決定怎麼關掉自己

public partial class Splash : PhoneApplicationPage
{
    public Splash()
    {
        InitializeComponent();
    }

    private void OnButtonClick(object sender, RoutedEventArgs e)
    {
        if (typeof(Popup) == this.Parent.GetType())
        {
            ((Popup)this.Parent).IsOpen = false;
        }
        else
        {
            if (NavigationService.CanGoBack)
            {
                NavigationService.GoBack();
            }
        }
    }
}

這頁偽 Splash 的 XAML 描述如下,重點只有一個,要指定明確的長寬,
且起始頁若不顯示 SystemTray,這一個偽 Splash 也要設為不顯示 SystemTray

<phone:PhoneApplicationPage
    x:Class="SplashTest.Splash"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="480"
    shell:SystemTray.IsVisible="False">

    <!--
    主容器尺寸一定要設為全螢幕或適當尺寸,此處設為 480 x 800,
    並將 SystemTray.IsVisible 設為 False 佔滿裝置螢幕,
    若沒有預先指定長寬,經由 Popup 顯示出來會是長寬皆為 0 的元件,
    -->
    <Grid x:Name="LayoutRoot" Background="Gray" Height="800" Width="480">
        <TextBlock Text="i am splash" Width="130" Height="38" Foreground="Red" FontSize="24"/>
        <Button Content="Close" Width="150" Height="80" Margin="0,120,0,0" Click="OnButtonClick"/>
    </Grid>
</phone:PhoneApplicationPage>



沒有留言:

張貼留言