张明云的知识共享 2018-03-21
概述
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 的内容主要包括以下几个部分:
这里我们定义了 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 = ;
// 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 类来实现进度条的显示和更新,如下图,它主要就以下几个属性:

接下来看一下代码示例:
// 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 = ;
ToastNotificationManager.CreateToastNotifier().Show(toast);下面是进度条更新的代码:
// 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 == )
{
    data.Values["progressValue"] = "0.7";
    data.Values["progressValueString"] = "7/10 files";
}
else if (seq_no == )
{
    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 有很大帮助。