第9回 効果的に情報を提示する:連載:Windowsストア・アプリ開発入門(3/7 ページ)
Windowsストアアプリの「タイル」や「トースト通知」などの情報提示手段について学び、「ライブタイル」と「セカンダリタイル」を実装してみよう。
ライブタイルを作る
さまざまな情報提示手段の中から、今回はローカル通知のライブタイルとセカンダリタイルを作ってみよう。まずは、ライブタイルから。
ライブタイルのスペックを考える
本連載で作ってきたアプリは、2つのRSSフィードをダウンロードしている。それぞれに含まれている記事タイトルの中から、新しいものをタイルに表示することにしよう。
ローカル通知のライブタイルでは、いつ処理をして/どんな内容を/どのように見せるかを決めておく。今回は以下のようにしよう。
- 通知の処理をいつ行うか?⇒RSSフィードをダウンロードしたとき
- 通知する内容は?⇒フィードのタイトル、および、記事のタイトルを新しいものから可能な限り
- どのように見せるか?⇒ワイドタイル(310×150ピクセル)と大タイル(310×310ピクセル)に以下のテンプレートを使って表示する
ライブタイルの外観は、タイル テンプレート カタログから選択する。使用する画像も決めておかねばならない。次のようにしよう。
ワイドタイル
ワイドタイルにはTileWide310x150PeekImage02テンプレートを使う。画像は、既定のワイドタイル用として第3回で作成したものをそのまま使おう。
大タイル
大タイルにはTileSquare310x310ImageAndTextOverlay03テンプレートを使う。画像は、既定の大タイル用に第3回で作成したものをそのまま使おう。
ライブタイルを実装する
ライブタイルの通知を登録するクラスを作り、それを呼び出すメソッドを書き、そのメソッドを呼び出すイベントを追加する。
ライブタイルの通知を登録するクラス
まず、ライブタイルの通知を登録するクラスを作る。プロジェクトに「Tile」というフォルダーを作り、そこに新しいクラスを「LiveTile.cs」というファイル名で作成する。
ライブタイルに必要な情報は、フィードのタイトルと記事のタイトルだけである。その情報を表すクラスから作る(次のコード)。
internal class LiveTileData
{
public string FeedTitle{get;set;} // フィードのタイトル
public IList<string> ArticleTitles = new List<string>(); // 記事のタイトルのコレクション
}
これはライブタイルの作成に必要な情報を表すクラスだ。
呼び出す側では、このLiveTileDataクラスのコレクションを用意して渡すようにしよう。すると、ライブタイルの通知を登録するUpdateLiveTileメソッドは、LiveTileクラスを作って次のように書ける。
internal static class LiveTile
{
public static void UpdateLiveTile(IEnumerable<LiveTileData> tileDataCollection)
{
// TileUpdateManagerクラスからTileUpdaterオブジェクトを取得する
var tileUpdater = Windows.UI.Notifications.TileUpdateManager.CreateTileUpdaterForApplication();
tileUpdater.EnableNotificationQueueForWide310x150(true); // ワイドタイル用のキューを有効化
tileUpdater.EnableNotificationQueueForSquare310x310(true); // 大タイル用のキューを有効化
tileUpdater.Clear(); // 既存の通知があるなら削除
foreach (var tileData in tileDataCollection)
{
// 300×150と300×300のライブタイルのコンテンツを表すXmlDocumentを作る
var wideXml = CreateWideTile(tileData); // このメソッドについては後述する
var largeXml = CreateLargeTile(tileData); // このメソッドについては後述する
// largeXmlの中にwideXmlをマージしてXMLを完成させる
Windows.Data.Xml.Dom.IXmlNode node = largeXml.ImportNode(wideXml.GetElementsByTagName("binding").Item(0), true);
largeXml.GetElementsByTagName("visual").Item(0).AppendChild(node);
// ライブタイル通知を生成し、TileUpdaterオブジェクトを通じて登録する
var tileNotification = new Windows.UI.Notifications.TileNotification(largeXml);
tileUpdater.Update(tileNotification);
}
}
……省略……
}
ライブタイルを出すにはこのようなステップを踏む。
1. TileUpdateManagerクラスからTileUpdaterオブジェクトを取得する
2. タイルを管理するキューを有効化する。既存のタイルがある場合は、不要なものを削除する
3. ライブタイルのコンテンツをXmlDocumentオブジェクトとして作成する
4. XmlDocumentオブジェクトからタイル通知オブジェクトを生成し、それをキューに登録する
ここで面倒なのが、ライブタイルのコンテンツをXmlDocumentオブジェクト(上記コード中のwideXml変数とlargeXml変数)として作成するコードだ。XMLをハードコーディングするのではなく、システムからXMLのテンプレートを取得してそれを加工することが推奨されている。ワイドタイルと大タイルのXmlDocumentオブジェクトを作るメソッドは次のようになる。
private static Windows.Data.Xml.Dom.XmlDocument CreateWideTile(LiveTileData tileData)
{
// TileWide310x150PeekImage02
// このテンプレートは次のようなXMLになっている(実際には値は入っていない)
// 下線の部分に実際の値をセットする
/*
<tile>
<visual version="2">
<binding template="TileWide310x150PeekImage02" fallback="TileWidePeekImage02">
<image id="1" src="image1.png" alt="alt text"/>
<text id="1">Text Field 1 (larger text)</text>
<text id="2">Text Field 2</text>
<text id="3">Text Field 3</text>
<text id="4">Text Field 4</text>
<text id="5">Text Field 5</text>
</binding>
</visual>
</tile>
*/
// テンプレートを取得する
Windows.Data.Xml.Dom.XmlDocument tileXml
= Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(
Windows.UI.Notifications.TileTemplateType.TileWide310x150PeekImage02);
// <image>タグの属性をセットする
Windows.Data.Xml.Dom.XmlNodeList tileImageAttributes = tileXml.GetElementsByTagName("image");
((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/WideLogo.png");
((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("alt", "@IT RSS Reader");
// <text>タグ(属性id=1〜5)を順にセットする
int index = 0;
tileXml.GetElementsByTagName("text")[index++].InnerText = tileData.FeedTitle;
foreach (var articleTitle in tileData.ArticleTitles)
{
tileXml.GetElementsByTagName("text")[index++].InnerText = articleTitle;
if (index > 4)
break;
}
return tileXml;
}
TileUpdateManagerオブジェクトからテンプレートを取得し、必要な値をセットする。XMLのツリー構造を操作するのが少々面倒である。
private static Windows.Data.Xml.Dom.XmlDocument CreateLargeTile(LiveTileData tileData)
{
// TileSquare310x310ImageAndTextOverlay03
// このテンプレートは次のようなXMLになっている(実際には値は入っていない)
// 下線の部分に実際の値をセットする
/*
<tile>
<visual version="2">
<binding template="TileSquare310x310ImageAndTextOverlay03">
<image id="1" src="image1.png" alt="alt text"/>
<text id="1">Text Field 1 (larger text)</text>
<text id="2">Text Field 2</text>
<text id="3">Text Field 3</text>
<text id="4">Text Field 4</text>
</binding>
</visual>
</tile>
*/
// テンプレートを取得する
Windows.Data.Xml.Dom.XmlDocument tileXml
= Windows.UI.Notifications.TileUpdateManager.GetTemplateContent(
Windows.UI.Notifications.TileTemplateType.TileSquare310x310ImageAndTextOverlay03);
// <image>タグの属性をセットする
Windows.Data.Xml.Dom.XmlNodeList tileImageAttributes = tileXml.GetElementsByTagName("image");
((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("src", "ms-appx:///Assets/LargeLogo.png");
((Windows.Data.Xml.Dom.XmlElement)tileImageAttributes[0]).SetAttribute("alt", "@IT RSS Reader");
// <text>タグ(属性id=1〜4)を順にセットする
int index = 0;
tileXml.GetElementsByTagName("text")[index++].InnerText = "¥n" + tileData.FeedTitle;
foreach (var articleTitle in tileData.ArticleTitles)
{
tileXml.GetElementsByTagName("text")[index++].InnerText = articleTitle;
if (index > 3)
break;
}
return tileXml;
}
TileUpdateManagerオブジェクトからテンプレートを取得し、必要な値をセットする。
これら2つのメソッドで作ったXmlDocumentオブジェクトを、UpdateLiveTileメソッドの中で1つにまとめてから、ライブタイルの通知を生成する。マージした後のXMLの例を次に示しておく。
<tile>
<visual version="2">
<binding template="TileSquare310x310ImageAndTextOverlay03">
<image id="1" src="ms-appx:///Assets/LargeLogo.png" alt="@IT RSS Reader"/>
<text id="1">¥r¥n@IT Insider.NETフォーラム</text>
<text id="2">ファイルアクセスの便利機能を使うには?</text>
<text id="3">第4回 ルーティングの設定/検証/例外処理</text>
<text id="4">第8回 入力されたデータを保存する</text>
</binding>
<binding template="TileWide310x150PeekImage02" fallback="TileWidePeekImage02">
<image id="1" src="ms-appx:///Assets/WideLogo.png" alt="@IT RSS Reader"/>
<text id="1">@IT Insider.NETフォーラム</text>
<text id="2">ファイルアクセスの便利機能を使うには?</text>
<text id="3">第4回 ルーティングの設定/検証/例外処理</text>
<text id="4">第8回 入力されたデータを保存する</text>
<text id="5">アプリのモダン化とその技術としての.NET Framework</text>
</binding>
</visual>
</tile>
XmlDocumentクラスのGetXmlメソッドを使って取得したXMLに、読みやすいように改行とインデントを入れてある。
上の2つのメソッド内のコメントに載せておいたテンプレートのXMLと見比べてみてほしい。両方の<binding>要素が入っている。
XMLを扱うコードは煩雑に見えるが、やっていることは値を当てはめて合体させているだけである。
Copyright© Digital Advantage Corp. All Rights Reserved.