Windows 10 UWP 6 of N : New Tile and Toast Notification
從Windows Phone 7.0 開始Windows就採用動態磚為App的外貌一直到現在Universal Windows App on Windows 10(以下皆簡稱UWP)都還是採用相同基礎的視覺體驗。
而User最直接看到的視覺體驗就是動態磚(Tile)、通知(Toast)的操作方式,問題是在Windows 和Windows Phone 的磚塊顯示依然有所區別,到了UWP才針對這部分有做了統一性的設計(當然還是有些許的差異~)
之前在Windows 8都是採用5px為基礎視覺單位值、在Windows 10則是採用4epx為單位。動態磚也分成四種大小
- Small 1x1
- Medium 2x2
- Wide 4x2
- Large 4x4 ( Desktop only. )
現在在Notification的樣板做了統一,所以出現了Adaptive Tile Template!如下的XML就是簡略的格式的Adaptive tile XML schema
<visual>
<binding template="TileMedium">
...
</binding>
<binding template="TileWide">
<text hint-style="subtitle">Jennifer Parker</text>
<text hint-style="captionSubtle">Photos from our trip</text>
<text hint-style="captionSubtle">Check out these awesome photos I took while in New Zealand!</text>
</binding>
<binding template="TileLarge">
...
</binding>
</visual>
</tile>
主要是有個tile的Root接著是visual,tile本身沒有其他Attribute。
version? = integer
lang? = string
baseUri? = anyURI
branding? = "none" | "logo" | "name" | "nameAndLogo"
addImageQuery? = boolean
contentId? = string
displayName? = string >
<!-- Child elements -->
binding+
</visual>
以上是visual的attribute
template = tileTemplateNameV3
fallback? = tileTemplateNameV1
lang? = string
baseUri? = anyURI
branding? = "none" | "logo" | "name" | "nameAndLogo"
addImageQuery? = boolean
contentId? = string
displayName? = string
hint-textStacking? = "top" | "center" | "bottom"
hint-overlay? = [0-100] >
<!-- Child elements -->
( image
| text
| group
)*
</binding>
接者是binding的部分有以上的attribute,這邊注意Child是可以做Grouping的喔!而template就是TileSmall、TileMedium、TileWide、TileLarge(只限桌面版本)。
src = string
placement? = "inline" | "background" | "peek"
alt? = string
addImageQuery? = boolean
hint-crop? = "none" | "circle"
hint-removeMargin? = boolean
hint-align? = "stretch" | "left" | "center" | "right" />
以上的則是image的相關格式
lang? = string
hint-style? = textStyle
hint-wrap? = boolean
hint-maxLines? = integer
hint-minLines? = integer
hint-align? = "left" | "center" | "right" >
<!-- text goes here -->
</text>
textStyle values...
caption
captionSubtle
body
bodySubtle
base
baseSubtle
subtitle
subtitleSubtle
title
titleSubtle
titleNumeral
subheader
subheaderSubtle
subheaderNumeral
header
headerSubtle
headerNumber
接著是文字的XML。
最後是Grouping的XML格式
<!-- Child elements -->
subgroup+
</group>
<subgroup
hint-weight? = [0-100]
hint-textStacking? = "top" | "center" | "bottom" >
<!-- Child elements -->
( text
| image
)*
</subgroup>
Group只能放個Subgroup然後Subgroup可以定義weight(Column)的比例!
假設定義了四個subgroup並都給予hint-weight都是1的話就會變成1/4(25%)
在subgroup裡面的text或image的xml都會是stack的方式堆疊
var text2 = new TextElement() { StringData = "t2" };
var image1 = new ImageElement() { ImageSource = "ms-appx:///Assets/Logo.png", IsRemoveMargin = true };
var image2 = new ImageElement() { ImageSource = "ms-appx:///Assets/Logo.png", IsRemoveMargin = true };
var subgroup1 = new SubGroupElement() { weight = 1, ChildElements = new ChildElement[] { text1, image1 } };
var subgroup2 = new SubGroupElement() { weight = 1, ChildElements = new ChildElement[] { text2, image2 } };
var group1 = new GroupElement() { Subgroups = new SubGroupElement[] { subgroup1, subgroup2 } };
var group2 = new GroupElement() { Subgroups = new SubGroupElement[] { subgroup1, subgroup2 } };
var visual = new VisualElement()
{
version = 3,
BindingElements = new BindingElement[]
{
new BindingElement() { TileTemplate = AdaptiveTileSizeEnum.TileWide, Group = group1 },
new BindingElement() { TileTemplate = AdaptiveTileSizeEnum.TileMedium, Group = group2 }
}
};
var tile = new TileElement() { visual = visual };
var notification = new TileNotification(AdaptiveTileHelper.TrySerializeToXml(tile));
TileUpdateManager.CreateTileUpdaterForApplication().Update(notification);
上述程式碼就可以產生如以下圖片
詳細更多Adaptive tile資料請參考以下網址
接者來介紹Toast!之前在Windows 8.1的時候Toast會出現在右上角的角落,在8.1的Template只能顯示單張圖片以及簡單文字。在UWP的樣板一樣增加了Adaptive toast。
<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>
如上是簡單的Adaptive toast的XML樣板,可以看到一樣的是會有個visual為主要的視覺部分;action則是可以進行一些行為的動作;最後audio則是跳出toast的聲音。
<visual addImageQuery="false" version="3">
<binding addImageQuery="false" template="ToastGeneric">
<text>this is title</text>
<text>this is content</text>
<image addImageQuery="false" hint-crop="circle" placement="appLogoOverride" src="ms-appx:///Assets/Logo.png"/>
<image addImageQuery="false" hint-crop="none" placement="inline" src="ms-appx:///Assets/IC716666.png" alt="override"/>
</binding>
</visual>
</toast>
現在可以將圖片嵌入在toast的Content之中了!
<visual addImageQuery="false" version="3">
<binding addImageQuery="false" template="ToastGeneric">
<text>title</text>
<text>content</text>
<image addImageQuery="false" hint-crop="circle" placement="appLogoOverride" src="ms-appx:///Assets/Logo.png"/>
<image addImageQuery="false" hint-crop="none" placement="inline" src="ms-appx:///Assets/IC716666.png" alt="override"/>
</binding>
</visual>
<actions hint-systemCommand="SnoozeAndDismiss">
<action content="primary" activationType="foreground" arguments="fitst"/>
<action content="secondary" activationType="background" arguments="secondary"/>
</actions>
</toast>
接者可以將Action加入在toast中。這邊需要注意的是要先用actions將兩個action包起來並且activation為foreground以及background。
<visual addImageQuery="false" version="3">
<binding addImageQuery="false" template="ToastGeneric">
<text>title</text>
<text>content</text>
<image addImageQuery="false" hint-crop="circle" placement="appLogoOverride" src="ms-appx:///Assets/Logo.png"/>
<image addImageQuery="false" hint-crop="none" placement="inline" src="ms-appx:///Assets/IC716666.png" alt="override"/>
</binding>
</visual>
<actions hint-systemCommand="SnoozeAndDismiss">
<input placeHolderContent="here" type="text" id="message">
</actions>
</toast>
接者可以放入輸入框。這邊注意的是在input的type為text!
<visual addImageQuery="false" version="3">
<binding addImageQuery="false" template="ToastGeneric">
<text>title</text>
<text>content</text>
<image addImageQuery="false" hint-crop="circle" placement="appLogoOverride" src="ms-appx:///Assets/Logo.png"/>
<image addImageQuery="false" hint-crop="none" placement="inline" src="ms-appx:///Assets/IC716666.png" alt="override"/>
</binding>
</visual>
<actions hint-systemCommand="SnoozeAndDismiss">
<input type="selection" id="selections" defaultInput="2">
<selection content="s1" id="1"/>
<selection content="s2" id="2"/>
<selection content="s3" id="3"/>
</input>
</actions>
</toast>
還可以放入selections!。需要注意的是type變成selection而內部的selection都會有id來做為index的區別要和defaultinput為同樣的格式(以上就是用數字型態)。
新版的toast因為可以執行輸入data給App所以就得在加Code來做些邏輯判斷。
前景執行(Foreground execute)的狀態,或是說APP在執行狀態。
{
if (args is ToastNotificationActivatedEventArgs)
{
var toastArgs = (ToastNotificationActivatedEventArgs)args;
var toastArgument = toastArgs.Argument;
var toastInput = toastArgs.UserInput["selections"];
}
base.OnActivated(args);
}
在App.xaml.cs檔案加入以上code的部分來進行擷取資料,這邊注意的是UserInput中的字串是在toast內的input的id!
背景執行(Background execute)的狀態,就是APP沒有在執行但toast跳出後的選擇後的執行方式。
<BackgroundTasks>
<Task Type="systemEvent"/>
<Task Type="general"/>
</BackgroundTasks>
</Extension>
先是註冊BackgroundTask在PackageManifest的Extension內,之前Preview版本使用的是systemEvent作為task的type但現在似乎轉為general!這個部分會等7/29上市後做測試。
然後寫上以下C#的程式碼註冊Background,而BackgroundTask的型態為ToastNotificationActionTrigger
接者建立BackgrountTask的C#檔案,並在其中寫入檔案中! 因為是背景啟動所以需要儲存為Storage。
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();
var localStorage = ApplicationData.Current.LocalFolder;
var detail = taskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
if (detail != null)
{
taskInstance.Canceled += TaskInstance_Canceled;
...
deferral.Complete();
}
}
private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
}
}
接著在MainPage.cs的OnNavigationTo的事件中將Storage的資料轉換成Object狀態就可以處裡接下來的邏輯了。
PS:程式碼的部分之後會再補上
更新1 現在測試BackgroundTask(以Timer為例)變更如下
ToastNotificationManager.CreateToastNotifier("App").Show(toast);
如果不給ApplicationId會丟出錯誤!
更新2 Github的網址
https://github.com/EvaRichie/UWP1.0
詳細更多Adaptive toast資料請參考以下網址
***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio 2015版本有所調整!***
參考資料 2-762 Tiles, Notifications and Action Center in Windows 10, MSDN Blogs
下次再分享Windows 10 的新技術拉~