概述 Toast Notification 在 UWP App 中有很重要的作用,能夠很大程度上增強 App 和用戶之間的溝通,比如運營推廣活動、版本更新、提醒類任務提示等等。Toast Notification 可以通過圖片、文字、按鈕等創建可適配、可交互的通知。 我們在 About Window ...
概述
Toast Notification 在 UWP App 中有很重要的作用,能夠很大程度上增強 App 和用戶之間的溝通,比如運營推廣活動、版本更新、提醒類任務提示等等。Toast Notification 可以通過圖片、文字、按鈕等創建可適配、可交互的通知。
我們在 About Windows 10 SDK Preview Build 17110 中對 Toast Notification 做了簡單的介紹,本篇會從開發角度更更深入的解讀。Toast Notification 主要分為網路內容通知和本地內容通知,本篇我們主要關註 Toast Notification 的以下新增功能的內容開發和顯示,對於觸發通知的源暫不細講:
- 圖片尺寸限制
- 進度條
- 新增的輸入選項
開發過程
NuGet 安裝
為了在 UWP 中實現 Toast Notification,我們需要引入一個 SDK:Microsoft.Toolkit.Uwp.Notifications ,通過 NuGet 在 Visual Studio 的Package Management 中安裝:
Install-Package Microsoft.Toolkit.Uwp.Notifications -Version 2.2.0
基礎實現
我們來實現一個樣式比較基礎的 Toast Notification,Toast 的內容主要包括以下幾個部分:
- Launch — 定義一個參數,當用戶點擊 Toast 時傳回到應用中,允許開發者深度鏈接到 Toast 顯示的正確內容對應的應用頁面內容中;
- Visual — Toast 的靜態內容展示部分,包括文本和圖像等;
- Actions — Toast 的可交互部分,包括可點擊的按鈕,文本輸入等;
- Audio — 當 Toast 顯示時,播放的音樂。
這裡我們定義了 ToastContent 需要的基本內容:
string title = "Shaomeng sent you a picture"; string content = "Check this out!"; string image = "ms-appx:///assets/test.jpg"; string logo = "ms-appx:///assets/shaomeng.jpg"; // Construct the visuals of the toast ToastVisual visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = title }, new AdaptiveText() { Text = content }, new AdaptiveImage() { Source = image } }, AppLogoOverride = new ToastGenericAppLogo() { Source = logo, HintCrop = ToastGenericAppLogoCrop.Circle } } }; // In a real app, these would be initialized with actual data int conversationId = 384928; // Construct the actions for the toast (inputs and buttons) ToastActionsCustom actions = new ToastActionsCustom() { Buttons = { new ToastButton("Like", new QueryString() { { "action", "like" }, { "conversationId", conversationId.ToString() } }.ToString()) { ActivationType = ToastActivationType.Background }, new ToastButton("View", new QueryString() { { "action", "viewImage" }, { "imageUrl", image } }.ToString()) } }; ToastAudio audio = new ToastAudio() { Src = new Uri("ms-appx:///assets/test.mp3", UriKind.RelativeOrAbsolute) };define content for Toast Content
使用上面的內容,定義一個 ToastContent,並把它顯示出來:
ToastContent toastContent = new ToastContent() { Launch = "test string", Visual = visual, Actions = actions, Audio = audio, }; var toast = new ToastNotification(toastContent.GetXml()); ToastNotificationManager.CreateToastNotifier().Show(toast);
圖片尺寸限制
Toast Notification 中允許使用的圖片來源包括:http://,ms-appx:///,ms-appdata:///
對於網路圖片,圖片尺寸限制的單位是單個圖片尺寸。16299 以後,normal connections 的限制是 3MB,metered connections 的限制是 1MB;而之前的限制統一是 200 KB。可以看到對網路圖片的尺寸限制放寬了很多,很多高清晰度的圖片也可以被使用。
如果你的圖片超過了這個尺寸限制,或者下載過程中失敗,超時,通知會正常被顯示,不過圖片部分會被放棄。
我們來做一下實際的驗證,上面示例中我們使用了一張 buildcast 低解析度 jpg 截圖,只有 50KB 左右,如果把上面示例中的圖片替換成 >3MB 的網路原始圖片:
string image = "http://192.168.1.110/buildcast.png";
buildcast.png 的尺寸是 5.63MB,看看顯示結果,確實放棄了圖片,只顯示了其他部分:
而如果使用同一張圖片,但是把放到工程里呢:
string image = "ms-appx:///assets/buildcast.png";
結果就是,圖片可以正常顯示了。這也印證了上面的結論,圖片尺寸限制只針對網路圖片:
進度條
在某些場景,例如下載或其他過程進行時,需要在通知中顯示進度條,讓用戶可以保持對進度的關註。進度條可以是不確定的或者確定的。
Toast Content 中,使用 AdaptiveProgressBar 類來實現進度條的顯示和更新,如下圖,它主要就以下幾個屬性:
- Title — 設置和顯示進度條的標題,支持 DataBinding;
- Value — 設置和顯示進度條當前進度,支持 DataBinding;預設值為 0.0,取值範圍是 0.0 ~1.0;AdaptiveProgressBarValue.Indeterminate 代表不確定值,顯示效果就是不斷移動的三個點,表示某個不確定過程正在進行;new BindableProgressBarValue("myProgressValue") 為數值綁定的寫法;
- ValueStringOverride — 設置和顯示重寫當前進度數值,支持 DataBinding;書寫方式為 new BindableString("progressValueString"),
- Status — 設置和顯示當前進度條狀態,支持 DataBinding;如下圖中的 Status 可能會有:downloading...,finished! 等;
接下來看一下代碼示例:
- 我們給 ToastContent 設置了 Tag(或 Group),作為更新顯示時的標識;
- AdaptiveProgressBar 中使用了 DataBinding 的方式來賦值,併在 Toast 第一次顯示時,手動給它設置了初始值;
- 設置了 Toast 的 SequenceNumber,它是一個 uint 類型,在更新時,只有值大於前一次的值才會更新;所以如果你想每次都更新,初始值可以設置為 0;
// Define a tag (and optionally a group) to uniquely identify the notification, in order update the notification data later; string tag = "demo-filelist"; string group = "downloads"; // Construct the toast content with data bound fields ToastContent content = new ToastContent() { Visual = new ToastVisual() { BindingGeneric = new ToastBindingGeneric() { Children = { new AdaptiveText() { Text = "Downloading your demo files..." }, new AdaptiveProgressBar() { Title = "Demo Files", Value = new BindableProgressBarValue("progressValue"), ValueStringOverride = new BindableString("progressValueString"), Status = new BindableString("progressStatus") } } } } }; var toast = new ToastNotification(content.GetXml()); // Assign the tag and group toast.Tag = tag; toast.Group = group; //Assign initial NotificationData values toast.Data = new NotificationData(); toast.Data.Values["progressValue"] = "0.0"; toast.Data.Values["progressValueString"] = "0/10 files"; toast.Data.Values["progressStatus"] = "Downloading..."; // Provide sequence number to prevent out-of-order updates, or assign 0 to indicate "always update" toast.Data.SequenceNumber = 0; ToastNotificationManager.CreateToastNotifier().Show(toast);
下麵是進度條更新的代碼:
- 註意 Tag 和 Group 需要和創建 Toast 時保持一致,不然更新不會生效;
- SequenceNumber 設置的值需要比上一次的大,不然更新也不會生效;
- 我們進行了兩次更新,一次是進行中,一次是已經完成;
// Construct a NotificationData object; string tag = "demo-filelist"; string group = "downloads"; // Create NotificationData and make sure the sequence number is incremented // since last update, or assign 0 for updating regardless of order var data = new NotificationData { SequenceNumber = seq_no }; // Assign new values if (seq_no == 1) { data.Values["progressValue"] = "0.7"; data.Values["progressValueString"] = "7/10 files"; } else if (seq_no == 2) { data.Values["progressValue"] = "1.0"; data.Values["progressValueString"] = "10/10 files"; data.Values["progressStatus"] = "Finished!"; } // Update the existing notification's data by using tag/group ToastNotificationManager.CreateToastNotifier().Update(data, tag, group);
來看看三個狀態,初始值,更新1-進行中,更新2-已完成:
新增的輸入選項
輸入區域會出現在 Toast 中的 Actions 區域,也就是說只有 Toast 被展開的時候,輸入區域才會顯示出來。下麵來看看幾種常見的輸入形式:
1. 快速回覆輸入
看一下輸入部分的代碼,添加了一個 ToastTextBox 來輸入文字,添加了一個 ToastButton 來處理輸入的文字,為了讓按鈕出現在文本框後面,ToastButton 的 TextBoxId 屬性設置為 ToastTextBox 的 Id。而點擊按鈕後的操作,屬於後臺操作,不需要啟動應用,也不需要關聯協議啟動其他應用。
// Construct the actions for the toast (inputs and buttons) ToastActionsCustom actions = new ToastActionsCustom() { Inputs = { new ToastTextBox("tbReply") { PlaceholderContent = "Type a reply" } }, Buttons = { new ToastButton("Reply", "action=reply&convId=9318") { ActivationType = ToastActivationType.Background, // To place the button next to the text box, // reference the text box's Id and provide an image TextBoxId = "tbReply", ImageUri = "Assets/if_paperfly_701491.png" } } };
運行效果如下圖,摺疊時文本框區域不顯示,而輸入文字點擊按鈕後,Toast 消失。
2. 帶按鈕欄輸入
帶按鈕欄的輸入相對更通用一些,輸入框後面顯示操作的若幹按鈕,點擊每個按鈕會有對應的操作
// Construct the actions for the toast (inputs and buttons) ToastActionsCustom actions = new ToastActionsCustom() { Inputs = { new ToastTextBox("tbReply") { PlaceholderContent = "Type a reply" } }, Buttons = { new ToastButton("Reply", "action=reply&threadId=9218") { ActivationType = ToastActivationType.Background }, new ToastButton("Video call", "action=videocall&threadId=9218") { ActivationType = ToastActivationType.Foreground } } };
3. 選擇式輸入
提供一個輸入選項給用戶,選擇某個選項後,點擊按鈕會有對應的操作
Inputs = { new ToastSelectionBox("time") { DefaultSelectionBoxItemId = "lunch", Items = { new ToastSelectionBoxItem("breakfast", "Breakfast"), new ToastSelectionBoxItem("lunch", "Lunch"), new ToastSelectionBoxItem("dinner", "Dinner") } } },
4. 提醒式輸入
基本構成和上面的選擇式輸入一致,只不過兩個 Action 按鈕是系統內置的按鈕類型:推遲和取消
Inputs = { new ToastSelectionBox("snoozeTime") { DefaultSelectionBoxItemId = "15", Items = { new ToastSelectionBoxItem("5", "5 minutes"), new ToastSelectionBoxItem("15", "15 minutes"), new ToastSelectionBoxItem("60", "1 hour"), new ToastSelectionBoxItem("240", "4 hours"), new ToastSelectionBoxItem("1440", "1 day") } } }, Buttons = { new ToastButtonSnooze() { SelectionBoxId = "snoozeTime" }, new ToastButtonDismiss() }
主要看兩個按鈕:ToastButtonSnooze - 推遲按鈕,根據上面 SelectionBox 選擇的值,在指定時間後再次提醒;ToastButtonDismiss - 取消按鈕,取消提醒;
到這裡就把 Windows 10 SDK 17110 中針對 Toast Notification 新增的內容介紹完了,大家如果對 Toast Notification 感興趣,可以做更深入的研究,相信一定會對你的 UWP App 有很大幫助。