Windows10的自适应和交互式toast通知是一个新特性。它可以让你:
创建灵活的toast通知,包括内嵌图片及更多的内容,不在局限于之前Windows 8.1和Windows Phone 8.1提供的toast模板。
关于Windows 8.1和Windows Phone 8.1遗留的模板介绍,请看 toast template catalog 。
在Windows10中,有以下几个方面,可以自定义已经存在的toast模板。
上面提到的内容本文都会介绍到。
在windows10中,开发者使用xml构造一个toast通知,它包含以下几个关键节点。
XML表示用户在界面上能看到的视觉内容,包括文本和图片,同样包含开发者想在通知内增加的自定义交互行为。
下面是个简单例子:
<toast launch="app-defined-string"> <visual> <binding template="ToastGeneric"> <text>Sample</text> <text>This is a simple toast notification example</text> <image placement="AppLogoOverride" src="oneAlarm.png" /> </binding> </visual> <actions> <action content="check" arguments="check" imageUri="check.png" /> <action content="cancel" arguments="cancel" /> </actions> <audio src="ms-winsoundevent:Notification.Reminder"/> </toast>
在visual节点内部,要求有一个binding节点,它包含visual模板信息和toast的视觉内容。
它不同于tile通知,可以在不同的tile大小上支持多个模板。Windows10中UWP应用的toast通知只有一个模板名称“ToastGeneric”。 相比之前遗留下的限制性模板,它有以下几个优势:
所有这些属性都会在visual部分和它的子节点中被支持。关于更多的例子,请看下面Samples部分。
在Windows10 UWP应用中,开发者可以添加自定义交互行为到toast通知里,它允许用户在app外做更多的事情。开发者能指定2个类型的节点:
提示: <action>和<input>在windows设备族里面是自适应的。比如,在windows移动和桌面上, <action>展示给用户的是一个触摸或点击,一个文本标记< input>展示的是一个输入框,用户可以通过键盘或虚拟键盘进行输入。 可能在不久后未来的设备上,行为是通过声音来触发的,文本框是通过用户语言识别来输入的。 toast通知内部的交互是能够适配这样的互动模式,消息内容显示能在设备上进行自适应的可视范围调整。
当一个行为被用户触发时,开发者能在<action>内activationType属性上选择下面的某一种方式去做对应处理:
所有上面提到的属性都会在<actions>部分和它的子节点上支持。
关于toast内部的交互,请看后面的例子。
在windows10 UWP应用中,其<audio>节点内容和WP8.1版本保持不变。
移动设备能通过ms-appx和ms-appdata自定义声音,但是桌面版不行。其二者都可以使用ms-winsoundevent。 关于toast上声音的更多信息,请看 audio schema page 。
在windows10上,开发者可以为闹钟、日历、来电去使用toast通知。 统一标准的toast通知从视觉上来看是一致的,用一些额外的UI策略会使通知适用每一个场景。
一个提醒的toast通知可以一直停在用户屏幕上,直到用户触发它的行为去忽略它或使用它。在windows移动设备上,提醒toast通知也将会同样的显示。
除了上面提醒的通知与行为,闹钟通知会自动播放声音。
来电通知会在windows移动设备上全屏显示。
这些可在toast通知的根节点<toast>内,通过指定“scenario”属性来完成。
请注意下面所有的toast通知是从windows桌面预览版系统得到的,toast通知的移动版本有时候会发生崩溃,这在后面会进行解释。
你可以在toast通知上使用多行文本,一个随意的小照片去覆盖应用的logo,一个随意内嵌的图片缩略图。
<toast launch="app-defined-string"> <visual> <binding template="ToastGeneric"> <text>Photo Share</text> <text>Andrew sent you a picture</text> <text>See it in full size!</text> <image placement="appLogoOverride" src="A.png" /> <image placement="inline" src="hiking.png" /> </binding> </visual> </toast>
<toast launch="app-defined-string"> <visual> <binding template="ToastGeneric"> <text>Microsoft Company Store</text> <text>New Halo game is back in stock!</text> <image placement="appLogoOverride" src="A.png" /> </binding> </visual> <actions> <action activationType="foreground" content="see more details" arguments="details" imageUri="check.png"/> <action activationType="background" content="remind me later" arguments="later" imageUri="cancel.png"/> </actions> </toast>
<toast launch="app-defined-string"> <visual> <binding template="ToastGeneric"> <text>Cortana</text> <text>We noticed that you are near Wasaki.</text> <text>Thomas left a 5 star rating after his last visit, do you want to try?</text> <image placement="appLogoOverride" src="A.png" /> </binding> </visual> <actions> <action activationType="foreground" content="reviews" arguments="reviews" /> <action activationType="protocol" content="show map" arguments="bingmaps:?q=sushi" /> </actions> </toast>
在这个例子中,你可以添加一个文本框,它允许用户输入文本。
如果允许用户通过输入内容来回复,你只需要关心一个场景即可,也可以使用下面的布局。 它仅仅适用于你的行为是一个指定的图片icon。
<toast launch="developer-defined-string"> <visual> <binding template="ToastGeneric"> <text>Andrew B.</text> <text>Shall we meet up at 8?</text> <image placement="appLogoOverride" src="A.png" /> </binding> </visual> <actions> <input id="message" type="text" placeholderContent="reply here" /> <action activationType="background" content="reply" arguments="reply" imageUri="send.png" hint-inputId="message"/> </actions> </toast>
在本例子中,可以添加一个下拉框列表,提供预先定义好的选项给用户选择。
<toast launch="developer-defined-string"> <visual> <binding template="ToastGeneric"> <text>Spicy Heaven</text> <text>When do you plan to come in tomorrow?</text> <image placement="appLogoOverride" src="A.png" /> </binding> </visual> <actions> <input id="time" type="selection" defaultInput="2" > <selection id="1" content="Breakfast" /> <selection id="2" content="Lunch" /> <selection id="3" content="Dinner" /> </input> <action activationType="background" content="Reserve" arguments="reserve" /> <action activationType="background" content="Call Restaurant" arguments="call" /> </actions> </toast>
注意:在这个提醒场景下,其图片会放大填充到整个toast通知的宽度。
<toast scenario="reminder" launch="developer-pre-defined-string"> <visual> <binding template="ToastGeneric"> <text>Adam's Hiking Camp</text> <text>You have an upcoming event for this Friday!</text> <text>RSVP before it"s too late.</text> <image placement="appLogoOverride" src="A.png" /> <image placement="inline" src="hiking.png" /> </binding> </visual> <actions> <action activationType="background" content="RSVP" arguments="rsvp" /> <action activationType="background" content="Reminder me later" arguments="later" /> </actions> </toast>
如上面提到的,toast的内容和行为是有能力通过不同的方式去触发app。下面的例子会展示并告诉你,怎么处理来自toast或toast行为的不同激活方式。
在这个场景下,app会启动它自身到前台,去响应toast通知内部的行为触发。 注意:toast通知的激活过去通常会调用OnLaunched()方法。在windows10上,toast有它自己激活方式,将会调用OnActivated()方法。
async protected override void OnActivated(IActivatedEventArgs args) { If (args.Kind == ActivationKind.ToastNotification) { //从事件参数中获取预定义的数据和用户输入 var toastArgs = args as ToastNotificationActivatedEventArgs; var arguments = toastArgs.Arguments; var input = toastArgs.UserInput[“1”]; } }
在这个场景下,app会使用一个后台任务去响应来自toast通知内部的行为触发。下面的代码会展示怎么在manifest内定义一个后台任务去处理toast的激活。 当一个后台任务被执行时,怎么得到行为上的详细参数和用户输入的内容。
<!-- 添加一个新的后台任务类型--> <Extension Category = "windows.backgroundTasks" EntryPoint = "Tasks.BackgroundTaskClass" > <BackgroundTasks> <Task Type="systemEvent" /> </BackgroundTasks> </Extension>
namespace ToastNotificationTask { public sealed class ToastNotificationBackgroundTask : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { //开发者可以在这里取回预定义的数据。 //参数和用户输入。 var details = taskInstance.TriggerDetails as ToastNotificationActionTriggerDetail; var arguments = details.Arguments; var input = details.Input.Lookup(“1”); } } }
注意:以下“?”表示一个属性是可选的。
<toast launch? duration? activationType? scenario? hint-people? > <visual version? lang? baseUri? addImageQuery? > <binding template? lang? baseUri? addImageQuery? > <text lang? >content</text> <text /> <image src placement? alt? addImageQuery? hint-crop? /> </binding> </visual> <audio src? loop? silent? /> <actions> </actions> </toast>
launch? | launch? = string,可选项。 当app被toast激活时,一个字符串会被传递给应用。它依赖activationType的值,app会在前台时接收,后台任务内接收,或者另外一个app接收(原app通过协议启动的)。字符串的格式和内容定义被app自己使用。当用户触摸或点击这个toast时,去启动它的相关联APP,这个启动字符串会提供给app,app允许展示给用户一个相关视图到toast内容上,而不是通过默认方式启动它。 注意:如果因为用户点击行为而发生替换toast内容。开发者应取回< action>标签上预定义的"arguments",而不是在< toast>预定义的"launch"值。 |
duration? | duration? = "short|long"。默认是short。 仅适用于特定场景和appCompat,再也不需要它配置闹钟场景。 除了office,它可能使用这弹出一个toast完成保存文件,再没有其他会使用这个属性了,如果你确实有一个真实场景需要它,请联系我们。 |
activationType? | activationType? = "foreground|background|protocol",可选属性,默认值是“foreground“。 |
scenario? | scenario? = "default|alarm|reminder|incomngCall",一个可选属性,默认值是“default“。 你不需要更改属性,除非你的场景是弹出一个闹钟、日历、或来电。不要使用这个属性去保持你的通知始终在屏幕上。 |
hint-people? | hint-people? = string 这个是为联系信息的可选属性。我们支持这个属性,但目前还没场景去使用这个值。 |
version? | version? = nonNegativeInteger 暂不需要, |
lang? | 请看 MSDN 。 |
baseUri? | 请看 MSDN 。 |
addImageQuery? | 请看 MSDN 。 |
template? | [重要] template? = "ToastGeneric"。 如果你使用任何新的自适应和交互功能,请确保你用ToastGeneric模板去替代遗留的模板。 |
lang? | 请看 MSDN 。 |
baseUri? | 请看 MSDN 。 |
addImageQuery? | 请看 MSDN 。 |
lang? | Please see MSDN for details on these existing optional attributes. |
<text /> | 当你想在2个文本节点中间添加一个空行时,可以使用它。 |
src | 请看MSDN |
placement? | placement? = "inline|appLogoOverride"可选的。 它指定图片将要显示在哪里。“inline”表示在toast内部文本的下面。“appLogoOverride” 意思是替换应用logo(它会现在toast的左上角部分)。每个placement值最多有一个图片。 |
alt? | 请看 MSDN . |
addImageQuery? | 请看 MSDN . |
hint-crop? | hint-crop? = "none" | "circle" ,可选的。 “none”是默认值,表示不裁剪。 “circle”表示会把这个图片裁剪成圆形,用它做联系人的头像、人的照片等等。作为metro2.0设计指南的一部分。 |
src? | 请看MSDN. |
loop? | 请看 MSDN . |
silent? | 请看 MSDN . |
<toast> <visual> </visual> <audio /> <actions> <input id type title? placeHolderContent? defaultInput? > <selection id content /> </input> <action content arguments activationType? imageUri? hint-inputId /> </actions> </toast>
id | id = string 这个id属性是必须的,一旦app被前台或后台激活,开发者可以通过它获取用户输入的内容。 |
type | type = "text|selection" 这个type属性是必须的。 它被用来指定是一个文本输入框或者预定义下拉列表输入框。 在移动或桌面,它指定你是想要一个textbox输入还是一个listbox输入。 |
title? | title? = string,可选的。 在输入框功能不能用时,它为开发者指定输入框的标题。 在移动和桌面上,这个标题会显示在输入框的上方。 |
placeHolderContent? | placeHolderContent? = string, 可选的。 当类型为text时,输入框不可见时会被显示。 当类型不是text时,它会被忽略。 |
defaultInput? | defaultInput? = string,可选的。 提供一个默认的文本框的值。 当类型为text,它作为一个纯文本显示。 当类型为selection时,它成为input内部可用选项的id。 |
content | content = string,必须的。 设置button的文本显示。 |
arguments | arguments = string 这个参数属性是app定义的数据,当app被用户行为激活时能获取到参数内容。 |
activationType? | activationType? = "foreground|background|protocol",可选的,默认“foreground”表示用户行为激活app的方式,是前台、后台任务、或者通过协议启动。 |
imageUri? | imageUri? = string,可选的。 它为显示的button内提供一个图片icon |
hint-inputId | hint-inputId = string,使用在快速回复场景。. |
除了上述选择外,在windows10中,如果app不想在后台任务内去处理通知的睡眠/忽略,我们也提供系统处理行为去睡眠或忽略通知。这些行为能被结合使用或单个指定使用,但是我们不推荐任何人在没有忽略行为时去实现一个睡眠行为。
<toast> <visual> </visual> <audio /> <actions hint-systemCommands? = "SnoozeAndDismiss" /> </toast>
hint- systemCommands | 如果你要发布一个移动app,目前不要使用。hint- systemCommands在移动上是损坏的,移动设备不需要用户选择睡眠时间。 仅适用于你发布desktop上使用。如果你二者平台都要发布,我们推荐使用下面的“个人处理行为”。 |
<toast> <visual> </visual> <audio /> <actions> <input id="snoozeTime" type="selection" defaultInput="10"> <selection id="5" content="5 minutes" /> <selection id="10" content="10 minutes" /> <selection id="20" content="20 minutes" /> <selection id="30" content="30 minutes" /> <selection id="60" content="1 hour" /> </input> <action activationType="system" arguments="snooze" hint-inputId="snoozeTime" content=""/> <action activationType="system" arguments="dismiss" content=""/> </actions> </toast>
构建个人睡眠和忽略行为,你需要做下面的事情。
Adaptive and interactive toast notifications for Windows 10