この記事では、Flash Lite 2.0で外部XML駆動型のフォトギャラリーを構築する方法について説明します(図1を参照)。このチュートリアルでは、主に、多数のサムネールやテキストをロードできるダイナミックリストの作成方法と、実行時に処理される各テキストに割り当てられる値を取り上げます。

図1. 最終的なアプリケーション
このチュートリアルを完了するには、次のソフトウェアをインストールする必要があります。また、Flash Lite 2.0が有効なモバイルデバイスにアクセスできる必要があります。
このアプリケーションの基本的な要素は次のとおりです。
プロジェクトには、データソースとアセットを保持する3つのフォルダがあります。これらは、上述のリンク先のサンプルファイルから取得できます。photoフォルダには8つの画像が含まれていて、thumbnailフォルダにそれぞれの画像のサムネールがあります。このサムネールがリストに表示されます。これらの画像の詳細は、xmlフォルダ内にあるxmllist.xmlというXMLファイルに記載されています(図2を参照)。

図2. このプロジェクトのファイル
プロジェクトのXMLファイル構造は非常に単純なXMLファイルで(図3を参照)、各ノードには、画像のタイトルであるlabelname、リストに表示する別のテキスト値date、Flashアプリケーションで処理するために各画像に追加する値itemvalueの3つの属性があります。

図3. プロジェクトのXMLファイル構造
xmllist.flaを開きます。_rootタイムラインに2つのフレームがあります。最初のフレームには、外部XMLファイルからデータをロードするリストがあります。もう1つのフレームには、ローダームービークリップによってリストで選択された画像がロードされます。
次に、フレーム1でActionScriptパネルを開きます。リストを有効にするために必要なActionScript 2.0コードを次に示します。
stop();
ムービーを最初のフレームに停止するためにこのコードが必要です。
ここで次のfscommand2コマンドを使用して画面を最大に引き伸ばします。モバイル画面で使用できるすべてのスペースを使用しましょう。
fscommand2("FullScreen", true);
XMLファイルからわかるように、各ノードには3つの属性があります。そのため、これらの各ノードを保持するには3つの配列を作成する必要があります。さらに、XMLのノードに関連する3つの属性を表示できるように、リストで特定のノードを示す必要があります。したがって、ノード値を格納するために別の配列が必要になります。つまり、XMLファイルで使用可能なデータをすべて格納するには4つの配列が必要です。それらの配列を次に示します。
var listArray:Array = new Array(); var photos:Array = new Array(); var labelname:Array = new Array(); var date:Array = new Array();
次のタスクはXMLファイルをロードして、これらの配列に必要な値を入力することです。そのためのActionScriptコードを次に示します。
var xmlFile:XML = new XML();
xmlFile.ignoreWhite = true;
xmlFile.load("xml/imagelist.xml");
xmlFile.onLoad = function(success) {
listArray = this.firstChild.childNodes;
for (i=0; i<listArray.length; i++) {
photos.push(listArray[i].attributes.itemvalue);
labelname.push(listArray[i].attributes.labelname);
date.push(listArray[i].attributes.date);
}
setListValues();
};
ここで、XMLファイルですべてのノードを探すためにforループを使用し、これらの値を対応する配列にプッシュしました。上のスクリプトで、XMLファイルのonLoad関数内にsetListValues();関数があります。この関数は、最初の4つのタブの値をリストに表示します。
次に、setListValues();関数を定義するコードを示します。
function setListValues(){
//set the active tab
moveValue = (maxLength/(photos.length));
select = 1;
list1.gotoAndStop(2);
//load first four tumbnails of the tabs
loadMovie("thumbnails/rose_thumb_"+photos[0]+".gif", "box1");
loadMovie("thumbnails/rose_thumb_"+photos[1]+".gif", "box2");
loadMovie("thumbnails/rose_thumb_"+photos[2]+".gif", "box3");
loadMovie("thumbnails/rose_thumb_"+photos[3]+".gif", "box4");
//Set initial text filed values of each tab
list1.labelnameValue = labelname[0];
list1.dateValue = date[0];
list2.labelnameValue = labelname[1];
list2.dateValue = date[1];
list3.labelnameValue = labelname[2];
list3.dateValue = date[2];
list0.labelnameValue = labelname[3];
list0.dateValue = date[3];
// Set initial values for _root timeline variables
_root.labelnameValue = labelname[0];
_root.dateValue = date[0];
_root.activeItemValue = photos[0];
ステージにはlist1、list2、list3、list0というインスタンス名を持つ4つのタブのリストがあります。これらはムービークリップの4つのコピーで、それぞれがリストのタブを表します。
各タブのムービークリップには2つのフレームがあります。デフォルトの選択されていないタブの状態を表すデフォルトのフレームと、ユーザがタブを選択したときのタブの状態(淡い緑色)を表すもう1つのフレームです(図4を参照)。

図4. ユーザがタブを選択してタブが淡い緑色になった状態
各フレームには2つのダイナミックテキストフィールドがあります。最初の1つは変数labelnameValueにリンクされ、もう1つはdateValueにリンクされています(図5を参照)。

図5. 各タブの2つのダイナミックテキストフィールド
_rootタイムラインのimageloaderというレイヤーには、サムネールがロードされる4つのタブにムービークリップの4つのコピーがあります。これらのサムネールローダーには、次のように、box1、box2、box3、box4というインスタンス名が指定されます(図6を参照)。

図6. サムネールローダー
4番目のlist0タブのインスタンスに名前を付けたのは、リスト全体に4つのタブを表示し、同時に、デバイスの上向きまたは下向き矢印キーで選択したタブを移動するときにそのタブをハイライト表示するためです。
例えば、ユーザが最初のタブで下向き矢印キーを押すと、上から2番目のタブがハイライト表示されます(図7を参照)。下向き矢印キーを再度押すと3番目のタブがハイライト表示され、もう一度押すと4番目のタブがハイライト表示されます。

図7. 最初の3つのタブのいずれかがすでに選択されている状態で下向き矢印キーを押すと、次のタブがハイライト表示される(リストの値は変わらない)
一方、4番目のタブを選択している状態で下向き矢印キーを押すと、ハイライト表示は最初のタブに移動し、同時に、4つのタブの値が個々の配列の次の4つの値に移動します(図8を参照)。

図8. 4番目のタブがすでに選択されている状態で下向き矢印キーを押すと、最初のタブがハイライト表示される(リストには配列の次の値セットが表示される)
この動作は、配列からデータの位置番号の剰余値を利用することで実現できます。
そのために、変数selectを利用します。この変数は、カウンタとして動作し、初期値を1に設定します。上向きまたは下向き矢印キーを押すと、このカウンタ値はそれぞれ1ずつ増減します。これで、select値が4または4の倍数になったときに、(select % 4)の値が1になります。
リストの移動の制御は、次のように、ステージの外側に配置したButtonコントロールというレイヤーにある汎用のボタンに割り当てられます。
on (keyPress "<Down>") {
if (select<photos.length) {
_root["list"+select%4].gotoAndStop(1);
setProperty("scrollBar_mc/thumb_mc", _y, getProperty("scrollBar_mc/thumb_mc", _y)+moveValue);
_root.select = select+1;
//trace(select);
//trace("thumbnails/"+photos[select-1]+"")
if ((select%4) == 1) {
loadMovie("thumbnails/rose_thumb_"+photos[select-1]+".gif", "box1");
list1.labelnameValue = labelname[select-1];
list1.dateValue = date[select-1];
loadMovie("thumbnails/rose_thumb_"+photos[select]+".gif", "box2");
list2.labelnameValue = labelname[select];
list2.dateValue = date[select];
loadMovie("thumbnails/rose_thumb_"+photos[select+1]+".gif", "box3");
list3.labelnameValue = labelname[select+1];
list3.dateValue = date[select+1];
loadMovie("thumbnails/rose_thumb_"+photos[select+2]+".gif", "box4");
list0.labelnameValue = labelname[select+2];
list0.dateValue = date[select+2];
}
_root["list"+select%4].gotoAndStop(2);
}
_root.labelnameValue = labelname[select-1];
_root.dateValue = date[select-1];
_root.activeItemValue = photos[select-1];
}
on (keyPress "<Up>") {
if (select>1) {
_root["list"+select%4].gotoAndStop(1);
_root.select = select-1;
//trace(select);
setProperty("scrollBar_mc/thumb_mc", _y, getProperty("scrollBar_mc/thumb_mc", _y)-moveValue);
if ((select%4) == 0) {
loadMovie("thumbnails/rose_thumb_"+photos[select-1]+".gif", "box4");
list0.labelnameValue = labelname[select-1];
list0.dateValue = date[select-1];
loadMovie("thumbnails/rose_thumb_"+photos[select-2]+".gif", "box3");
list3.labelnameValue = labelname[select-2];
list3.dateValue = date[select-2];
loadMovie("thumbnails/rose_thumb_"+photos[select-3]+".gif", "box2");
list2.labelnameValue = labelname[select-3];
list2.dateValue = date[select-3];
loadMovie("thumbnails/rose_thumb_"+photos[select-4]+".gif", "box1");
list1.labelnameValue = labelname[select-4];
list1.dateValue = date[select-4];
}
_root.labelnameValue = labelname[select-1];
_root.dateValue = date[select-1];
_root.activeItemValue = photos[select-1];
_root["list"+select%4].gotoAndStop(2);
}
}
on (keyPress "<Enter>") {
_root.gotoAndStop(2);
}
図9に示すように、Enterキーを押してユーザが_rootタイムラインのフレーム2に移動すると、フレーム2にはimageLoaderというインスタンス名の画像ローダームービークリップがあり、その上部には、画像のタイトルを表示するために変数_root.labelnameValueと_root.dateValueにリンクされている2つのテキストフィールドがあります。

図9. アプリケーションシェル
これで、様々な用途に利用できる、使いやすい外部データ駆動型のフォトギャラリーをFlash Lite 2.0で作成できました。
Flash Lite 2.0でよりダイナミックで複雑なアプリケーションを作成するためXML構文解析の知識を高めるには、Sas Jacobs著の『Foundation XML for Flash*』(Friends of ED Publishers、2005)をお読みください。
Samir K. DashはEnterprise System Solutions Pvt.Ltd.*のシステムコンサルタント(独創的なコンテンツ)で、Flashテクノロジを使用したEラーニングとインタラクティブなデザインを担当しています。 仕事以外では、夫人のSangeetaと一緒に過ごし、詩を書くことを楽しみにしています。