博客園客戶端(Universal App)開發隨筆 - Setting Page的實現方法與經驗

前言

幾乎全部的移動 App 都會爲用戶提供一個設置頁面(Setting Page 或 Preference Page),來知足你們對於一個 App 衆口難調的需求。雖然有一種說法表示,最好的 App 不須要設置,一切默認呈現給用戶的就是最好的選擇。可是對於大多數開發人員來講,這樣的境界不是能夠簡單達到的;並且對於部分「設置控」用戶來講,沒有設置頁面怎麼看都以爲少了些什麼。因此對於大部分 App 來講,設置頁面仍是一個必備品。windows

本文將分別介紹 Windows 和 Windows Phone 的設置頁面的界面設計,最後介紹他們後臺的統一實現與數據保存。網絡

 

Windows App 的Setting界面設計

在 Windows App 中,設置頁面的入口被統一在了 charm bar 中,手指從觸摸屏右側滑入或鼠標從屏幕右下角向下滑動均可以調出 charm bar,而後進入默認的設置頁面。app

screenshot_12112014_164857

開發中的默認的設置頁面只有 Permissions (權限)一項,發佈在市場後會自動添加 Rate and Review (評分)這一項,因此沒必要本身實現,可是在Windows Phone中須要本身實現。框架

screenshot_12112014_165037

對於一個通常的 App 來講,能夠在設置頁面添加以下幾項:async

  • 選項 / 偏好 (Option / Preference)
  • 關於(About)
  • 隱私聲明(Privacy Statement)(若是 App 使用了網絡權限,則這一項必選)

 

選項 / 偏好 (Option / Preference)

以博客園應用下一版即將加入的閱讀模式爲例。咱們但願在選項中新增閱讀模式的設置,具體實現方式爲在 App 的設置中增長選項一欄,點擊後跳轉到選項頁面,並進行相應設置。ide

首先咱們在 Universal App 中添加一個 Setting Flyout 頁面:動畫

1

在XAML部分,咱們加入簡單的說明與一個 ToggleButton。網站

<StackPanel Style="{StaticResource SettingsFlyoutSectionStyle}">
            <TextBlock Text="閱讀設置" Style="{StaticResource TitleTextBlockStyle}"/>
            <TextBlock Margin="0,0,0,10" Text="在閱讀設置部分,能夠進行全部和閱讀相關的設置" Style="{StaticResource BodyTextBlockStyle}"/>
            <ToggleSwitch Margin="-6,0,0,0" x:Name="ReadingModeToggle"
                          Header = "閱讀模式" HorizontalAlignment="Left" HorizontalContentAlignment="Left" OffContent="日間模式" OnContent="夜間模式" Toggled="ReadingModeToggle_Toggled"/>
        </StackPanel>

這樣就實現了一個最簡單的 SettingFlyout 頁面。那麼如何在 App 中調出這個頁面呢?咱們在App.xaml.cs文件中添加以下代碼:ui

#if WINDOWS_APP
using Windows.UI.ApplicationSettings;
#endif

並在 OnLaunched 方法內添加:this

#if WINDOWS_APP
            SettingsPane.GetForCurrentView().CommandsRequested += (s, args) =>
            {
                Add an About command to the settings pane
                var preference = new SettingsCommand("設置", "設置", (handler) =>
                new PreferenceSettingsFlyout().Show());
                args.Request.ApplicationCommands.Add(preference);
            };
#endif

這樣,打開應用時,在右側的 Setting Pane 中就增長了咱們的選項一欄,並能夠打開進行設置。

screenshot_12112014_165338screenshot_12112014_165344

具體設置的後臺實現,能夠經過 Toggled="ReadingModeToggle_Toggled" 調用後臺的具體方法實現。這一部分的有關內容將在後文提到。

關於(About)

關於(About)頁面能夠放置 App 相關的介紹與做者聯繫方式等信息,具體的實現與選項 / 偏好 (Option / Preference) 頁面類似,此處再也不贅述。

隱私聲明(Privacy Statement)

這一項比較特殊,凡是申請了網絡權限,包括 internetClient,internetClientServer 和 privateNetworkClientServer 權限的 App,都必須提供隱私聲明。開發者能夠在本身的網站或博客創建一個專門的頁面用來放置應用的隱私聲明,並在設置欄中提供一個轉向的入口,這樣才能確保 App 在提交時經過審覈。

因爲只須要跳轉的連接,因此隱私聲明的實現比較簡單。首先在 App.xaml.cs 的 OnLaunched 方法內添加:

#if WINDOWS_APP
                var privacy = new SettingsCommand("隱私聲明", "隱私聲明", GetPrivacyPolicyAsync);
                args.Request.ApplicationCommands.Add(privacy);
#endif

提供隱私聲明的入口,並在 App.xaml.cs 中添加如下方法:

#if WINDOWS_APP
        private async void GetPrivacyPolicyAsync(Windows.UI.Popups.IUICommand command)
        {
            await Windows.System.Launcher.LaunchUriAsync(new Uri("http://www.microsoft.com/privacystatement/zh-cn/core/default.aspx"));
        }
#endif

便可以實現。其中的 URL 請替換爲適合 App 自己的隱私聲明地址。

 

Windows Phone App的Setting界面設計

Windows Phone App 與 Windows App 在設置界面方面有兩點不一樣:

1. Windows Phone 沒有提供統一的設置入口。

2. Windows Phone App 不須要強制提供隱私聲明。

所以,開發者須要本身爲設置界面提供入口和界面頁面。以博客園 UAP 的 Windows Phone 版舉例,首先咱們在項目中添加 SettingPage.xaml。

2

博客園的設置頁面實現使用了 Pivot,好處是能夠在一個頁面同時實現「選項」與「關於」兩項內容,而且未來能夠很方便地添加新的子項。

<Pivot x:Name="pivot_Main" SelectionChanged="Pivot_SelectionChanged">
        <PivotItem Margin="0" Tag="setting">
            <PivotItem.Header>
                <TextBlock Style="{StaticResource PivotTitleFont}" Text="設置" />
            </PivotItem.Header>
            <StackPanel Orientation="Vertical" Margin="20">
                <ToggleSwitch Header="博客標題/摘要" OffContent="只顯示標題" OnContent="顯示標題和摘要" IsOn="{Binding DefaultDisplaySummary, Mode=TwoWay}"/>
                    <TextBlock Text="(刷新生效)" Foreground="{ThemeResource CNBlogsAttributionColor}" FontSize="14" Margin="0,-5,0,10"/>
                <ToggleSwitch Header="點擊博客標題時" OffContent="閱讀正文" OnContent="顯示/隱藏摘要" IsOn="{Binding ClickTitleForSummary, Mode=TwoWay}"/>
                    <TextBlock Text="(刷新生效)" Foreground="{ThemeResource CNBlogsAttributionColor}" FontSize="14" Margin="0,-5,0,10"/>
            </StackPanel>
        </PivotItem>

        <PivotItem Margin="0" Tag="about">
            <PivotItem.Header>
                <TextBlock Style="{StaticResource PivotTitleFont}" Text="關於" />
            </PivotItem.Header>
            <StackPanel Margin="20" HorizontalAlignment="Center">
                    <Image x:Name="image_Logo" Height="100" Margin="0,20" Source="ms-appx:///Assets/Logo.100.Blue.png" Opacity="0">
                    <Image.Projection>
                        <PlaneProjection />
                    </Image.Projection>
                </Image>
                <StackPanel x:Name="sp_aboutContent" Opacity="0">
                        <TextBlock Margin="0,10" HorizontalAlignment="Center" Style="{StaticResource SettingPageTextHeader}" Text="博客園" />
                        <TextBlock Margin="0,10" HorizontalAlignment="Center" Style="{StaticResource SettingPageTextHeader}" Text="Windows Phone 客戶端" />
                    <TextBlock HorizontalAlignment="Center" FontSize="14" Style="{StaticResource SettingPageTextHeader}" Text="Powered By Microsoft" />
                    <TextBlock x:Name="tbkVersion" Text="1.0" HorizontalAlignment="Center" FontSize="14" Style="{StaticResource SettingPageTextHeader}"/>
                    <HyperlinkButton x:Name="btn_RateMe" Margin="0,40,0,10" Content="給個好評" Style="{StaticResource SettingPageHyperlinkButtonText}" HorizontalAlignment="Center" Click="btn_RateMe_Click"/>

                        <TextBlock Margin="30" FontSize="14" FontFamily="Segoe WP" TextWrapping="Wrap" Foreground="{ThemeResource CNBlogsSummaryColor}">
                        <Run Text="本應用爲Universal App的示例應用,使用WindowsRT SDK開發,支持Windows Phone 8.1。"/>
                        <Run Text="還有一個同名應用同時發佈在Windows 8.1上,二者共用一套底層代碼。"/>
                    </TextBlock>
                </StackPanel>
            </StackPanel>
        </PivotItem>
    </Pivot>

經過以上代碼框架實現設置和關於頁面的內容填充,便可實現簡單的設置頁面效果。

34

在「關於」頁面中的那個「給個好評」,必須本身實現,兩行代碼搞定:

var uri = new Uri(string.Format("ms-windows-store:navigate?appid={0}", urrentApp.AppId));
await Windows.System.Launcher.LaunchUriAsync(uri);

 上面的那個版本號,也能夠用code從Package.appxmanifest中的這裏讀取:

<Identity Name="36385XiaowuHu.100280B26F648" Publisher="CN=60BC9EB8-6EF8-44C4-817C-FCE25D428B9B" Version="1.0.0.18" />

 

在博客園 Universal App 中,Windows Phone 版的設置頁面的入口是 BottomAppBar 中定義的

<AppBarButton x:Name="btn_Setting" Label="設置" Icon="Setting" Click="btn_Setting_Click"/>

按鈕提供的。這也是大多數 Windows Phone App 的設置頁面的入口。

5

 

除了 AppBarButton 之外,咱們還能夠經過更快捷的方式直接進入設置的具體頁面。例如咱們在 BottomAppBar 中添加

<CommandBar.SecondaryCommands>
                <AppBarButton x:Name="btnAbout" Label="關於本應用" Click="btnAbout_Click" />
</CommandBar.SecondaryCommands>

6

並在後臺實現點擊事件對應的方法:

private void btnLogon_Click(object sender, RoutedEventArgs e)
        {
            this.Frame.Navigate(typeof(SettingsPage), new DataModel.SettingNavigationParameter() { targetPivot = TargetPivotItemName.About, targetCss = 0 });
        }

便可直接跳轉到對應的關於頁面。這樣除了統一的設置入口之外,在不一樣頁面添加適應不一樣頁面的不一樣快捷入口,使得用戶能夠根據當前頁面快速找到對應設置選項。這是一個很是好的實踐經驗和用戶體驗,即,在不一樣上下文時提供不一樣的設置入口,好比在Reading Page,能夠提供「設置字號」菜單進入Setting Page;在Write Comment Page能夠提供「登陸」菜單進入Setting Page。

設置頁面的後臺實現與數據保存

全部設置頁面的操做,例如對 ToggleButton 的拖動,對 Button 的點擊等等,均可以經過填寫控件自己提供的事件方法來進行相應的操做,此處就再也不贅述。那麼當用戶進行設置之後,如何保存用戶的設置,使得用戶每次打開 App 都應用上次保存的設置內容呢?

在 App 中經常使用的保存數據有 XML 序列化和保存 Setting 字段兩種方式,前者主要適用於保存結構化的數據,對於簡單的設置數據的保存,咱們在博客園應用中使用了後者。

咱們在 CNBlogs.DataHelper.DataModel 的命名空間下添加 Setting.cs 用於定義各設置數據。以夜間模式舉例,在此類中添加以下定義:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;

namespace CNBlogs.DataHelper.DataModel
{
    public sealed class CNBlogSettings : DataModelBase
    {
        private ApplicationDataContainer settings = Windows.Storage.ApplicationData.Current.LocalSettings;

        const string SettingKey_NightModeTheme = "cnblog_night_mode_theme";

        public bool NightModeTheme
        {
            get
            {
                var obj = this.settings.Values[SettingKey_NightModeTheme];
                return obj == null ? false : (bool)obj;
            }
            set
            {
                this.settings.Values[SettingKey_NightModeTheme] = value;
                base.OnPropertyChanged("NightModeTheme");
            }
        }
    }
}

就實現了簡單的 NightModeTheme 字段的本地保存。爲了保持一致性,還能夠將 Setting 類設計爲單例模式。

這樣,在 ToggleButton 提供的事件方法中,咱們能夠對 NightModeTheme 字段進行修改,Setting 類會負責讀取與保存該字段的內容。

固然,可不能夠不經過 C# 代碼也能實現對 Setting 字段的修改呢?固然能夠。XAML 的數據綁定爲此提供了更優雅的解決方案。咱們只須要在夜間模式對應的 ToggleButton 中的XAML定義中添加 IsOn="{Binding NightModeTheme, Mode=TwoWay}" 這麼一個屬性,就能夠綁定 ToggleButton 的狀態與 Setting 類中 NightModeTheme 的值了。固然,根據 NightModeTheme 的值來進行怎樣的操做,如提供夜間模式變換主題狀態等操做,仍是須要後臺代碼實現的。

總結

本文介紹對 Windows App 和 Windows Phone App 設置界面的簡單設計,並給出了後臺代碼和數據保存的基本實現。經過這些,Universal App 就能夠擁有一個看起來像模像樣的設置頁面了。至於如何設計更加人性化,更加「高大上」的設計界面,就須要開發者們努力實現了。好比在咱們的博客園客戶端中的關於界面,實現了一個超出用戶預期的小動畫。歡迎交流。

 

你能夠從這裏下載咱們分享的源代碼:

https://code.msdn.microsoft.com/CNBlogs-Client-Universal-477943ab

固然更能夠直接下載兩個App來看效果,可是因爲designer介入較晚,因此UI上面還須要完善,咱們會持續更新App。

Windows Phone Store App link:

http://www.windowsphone.com/zh-cn/store/app/博客園-uap/500f08f0-5be8-4723-aff9-a397beee52fc

Windows Store App link:

http://apps.microsoft.com/windows/zh-cn/app/c76b99a0-9abd-4a4e-86f0-b29bfcc51059

純粹乾淨的App, 裏面絕無廣告,請放心使用。

 分享代碼,改變世界!

MSDN官方文檔:

Quickstart: Add app settings (XAML)

http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh872190.aspx

Guidelines for app settings

http://msdn.microsoft.com/en-us/library/windows/apps/hh770544.aspx

Adding app settings (XAML)

http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh770543.aspx

App certification requirements for the Windows Store

http://msdn.microsoft.com/en-us/library/windows/apps/hh694083.aspx

Loading and saving settings

http://msdn.microsoft.com/en-us/library/windows/apps/dn263230.aspx

相關文章
相關標籤/搜索