用戶打開應用後看到的第一個畫面就是啓動屏幕,雖說啓動屏幕作的好壞對應用的最終功能影響不大,可是對用戶來講,第一印象很是重要;另外,用戶每次運行應用也都會看到啓動屏幕,所以,啓動屏幕的地位也仍是挺重要的。html
應用在顯示主界面前,須要初始化一些數據,複雜一些的應用,其初始化用時也會長一些,可能須要初始化一些基礎組件、登陸到遠程服務器、從遠程同步數據等等,這些都會致使啓動屏幕存在較長的時間,同時,默認的啓動屏幕是一個靜態的畫面,用戶會感受體驗很差。若是咱們能夠將啓動屏幕作的生動一些,就可使得用戶體驗好一些。windows
下面咱們將討論兩種啓動屏幕的實現。服務器
能夠添加一個頁面,用來顯示新的啓動屏幕,在這個頁面中,咱們還能夠加入進度條和動畫效果,顯得生動一些,而後將主界面前的初始化操做都加在這個頁面中。具體實現步驟以下:app
具體頁面顯示的內容,你們能夠按本身的須要來設計,同時能夠加入一些動畫,使得等待再也不枯燥,再也不細說。async
啓動時跳轉到咱們新加的啓動頁面,同時將啓動事件參數傳進來,可能會在後續導航中用到。ide
protected override void OnLaunched(LaunchActivatedEventArgs e) { Frame rootFrame = Window.Current.Content as Frame; if (rootFrame == null) { // 將LaunchActivatedEventArgs傳入,這樣SplashPage中能夠根據啓動參數完成正確的跳轉 SplashPage splashPage = new SplashPage(e); Window.Current.Content = splashPage; } Window.Current.Activate(); }
響應Page的Loaded事件,在事件處理中,進行必要的初始化任務;在任務完成後,跳轉到正確的後續頁面。佈局
private async void Page_Loaded(object sender, RoutedEventArgs e) { // 必要的初始化任務 await Task.Delay(5000); // 後續跳轉 Frame rootFrame = new Frame(); // 此處須要根據SplashPage構造時傳入的LaunchActivatedEventArgs作對應跳轉 rootFrame.Navigate(typeof(MainPage)); Window.Current.Content = rootFrame; }
打開應用清單,在可見資產中的初始屏幕中,修改背景色和SplashPage一致,確保能夠平滑過渡;修改初始屏幕用到的圖片資源爲全透明。動畫
如今運行一下程序,能夠看到效果已經出來了,可是SplashPage的標題欄和默認啓動屏幕的標題欄不一致,若是介意此處不一致,能夠用以下code來修改標題欄。spa
// 針對mobile if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar")) { // 須要引用Windows Mobile Extensions for the UWP StatusBar sb = StatusBar.GetForCurrentView(); // 背景色設置爲須要顏色 sb.BackgroundColor = Color.FromArgb(255, 100, 149, 237); sb.BackgroundOpacity = 1; } // 針對desktop ApplicationView appView = ApplicationView.GetForCurrentView(); ApplicationViewTitleBar titleBar = appView.TitleBar; // 背景色設置爲須要顏色 Color bc = Color.FromArgb(255, 100, 149, 237); titleBar.BackgroundColor = bc; titleBar.InactiveBackgroundColor = bc; // 按鈕背景色按需進行設置 titleBar.ButtonBackgroundColor = bc; titleBar.ButtonHoverBackgroundColor = bc; titleBar.ButtonPressedBackgroundColor = bc; titleBar.ButtonInactiveBackgroundColor = bc;
以上改造後,就能夠看到咱們啓動屏幕的真實效果了。注意,因爲在SplashPage出現以前,會顯示系統的純色啓動屏幕,因此咱們應儘可能將全部初始化相關的操做放在SplashPage中,而不要放在App.xaml.cs中,以減小純色頁面的顯示時間。設計
上面的方案,一開始會有短暫的純色頁面,咱們但願可以保留系統的啓動屏幕,顯示應用的LOGO,而後平滑過渡到自定義的頁面上。下面講一下咱們的一些探索和實現。
基本思路是,添加一個新頁面,用應用清單中指定給啓動屏幕的背景色和圖片資源來設計頁面;而後在頁面加載時,根據系統啓動屏幕中圖片的位置來調整當前頁面中的圖片位置;另外,當頁面的大小發生變化時,須要對當前頁面從新調整。
在延長顯示初始屏幕的時間裏,已經有了詳細的實現步驟,能夠很快的完成這種啓動屏幕的實現,這裏再也不贅述。下面主要講一下采用這種實現,咱們遇到的一系列問題。
運行一下,效果不錯,不會出現第一種方案的純色界面。可是當咱們在手機模擬器上運行時,出現了嚴重問題,圖片的大小徹底對不上,調試跟蹤了一下發現,在手機上,SplashScreen中給出的系統圖片的大小是手機的物理分辨率,須要按當前設置的顯示比例計算一下才能獲得應該顯示的大小。
所以,咱們將計算圖片位置的代碼改成以下
void PositionImage() { // desktop if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily.Equals("windows.desktop", StringComparison.CurrentCultureIgnoreCase)) { extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X); extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y); extendedSplashImage.Height = splashImageRect.Height; extendedSplashImage.Width = splashImageRect.Width; } // mobile else if (Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily.Equals("windows.mobile", StringComparison.CurrentCultureIgnoreCase)) { // 獲取一個值,該值表示每一個視圖(佈局)像素的原始(物理)像素數。 double density = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel; extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X / density); extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y / density); extendedSplashImage.Height = splashImageRect.Height / density; extendedSplashImage.Width = splashImageRect.Width / density; } // xbox等沒試過,編不出來 else { } }
再運行一下,在手機模擬器上,啓動圖片的大小一致了,能夠銜接的上,可是圖片的位置仍是會向下抖一下,目測抖動的高度正好是手機狀態欄的高度。所以,咱們能夠用下面的代碼將頁面撐滿手機屏幕。
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.UI.ViewManagement.StatusBar")) { // 須要引用Windows Mobile Extensions for the UWP StatusBar sb = StatusBar.GetForCurrentView(); // 調整爲透明,也能夠用啓動屏幕的背景色+不透明 sb.BackgroundOpacity = 0; // 撐滿手機屏幕 Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().SetDesiredBoundsMode(Windows.UI.ViewManagement.ApplicationViewBoundsMode.UseCoreWindow); }
注意,以後跳到主界面時,須要根據實際狀況決定是否將對應的值改回來。
手機模擬器調好了,使用真實手機運行,有較大機率會看到,在系統啓動屏幕和新啓動屏幕之間切換時,會輕微閃動一下。緣由是系統啓動屏幕消失時,新啓動屏幕的圖片尚未加載渲染完成,所以,須要在圖片渲染完成後,再切到新啓動屏幕。
這裏能夠這樣作,在App.xaml.cs中不調用激活當前窗品,而後在ImageOpened事件處理中,啓動定時器,50ms後再激活當前窗口。
主要代碼以下
private DispatcherTimer showWindowTimer; private void OnShowWindowTimer(object sender, object e) { showWindowTimer.Stop(); // Activate/show the window, now that the splash image has rendered Window.Current.Activate(); } private void extendedSplashImage_ImageOpened(object sender, RoutedEventArgs e) { // ImageOpened means the file has been read, but the image hasn't been painted yet. // Start a short timer to give the image a chance to render, before showing the window // and starting the animation. showWindowTimer = new DispatcherTimer(); showWindowTimer.Interval = TimeSpan.FromMilliseconds(50); showWindowTimer.Tick += OnShowWindowTimer; showWindowTimer.Start(); }
偶現啓動屏幕縮在手機的左上角,如圖。
這是用戶反饋的問題,目前共接到兩起反饋,不易復現,咱們也只偶現過一次,還沒有找到緣由。
針對用戶截圖的顯示效果,猜想有可能復現該問題時,取到的圖片的尺寸信息不是手機設備的分辨率,好比可能寬大於高,所以咱們針對性的添加了部分處理代碼,不肯定是否能夠解決該問題,待下個版本旺信上線後,再看是否還有用戶反饋該問題。此處就不上代碼了。
方案一的優勢是,新啓動屏幕的界面設計比較自由,能夠任意發揮,同時,能夠很好的在不一樣設備上適配;缺點是,一開始會有一小段時間的純色屏幕,在低配的手機上比較明顯。
方案二的優勢是,將系統啓動屏幕和新啓動屏幕作到了平滑過渡;缺點是界面設計時要考慮到系統啓動屏幕的顯示,設計受限,同時,在不一樣類型設備上,系統傳入的啓動屏幕位置不一樣,須要針對性的進行調整。