OpenLaszloでマルチデバイス対応RIAを作ろう

第13回FlashライクなiPhone/iPod touch対応サイトの作成その2]

前回に引き続き、iPhone/iPod touch対応サイト完成品デモのソース詳解です。

ボタン

リスト1
<!--ボタン-->
<button id="btn" width="${canvas.width}" height="40" fontsize="18" fontstyle="bold">更新
  <handler name="onclick">
    if(this.text=="更新"){
      ds.doRequest(); //(1)
    }else{
      this.setAttribute('text',"更新"); //(2)
      showLeft.doStart(); //(3)
    }
  </handler>
</button>

画面上部のボタンです。1つの<button>タグで、更新ボタンと戻るボタンを兼ねています。

「<button>更新</button>」という書き方は「<button text="更新"></button>」という書き方と同じ意味になります。text属性の値を調べれば、ボタンの文字列によって挙動を変えることができます。またtext属性値を変更することでボタン文字列を動的に変更することができます。

(1) ds.doRequest()はデータセットdsに対してリクエスト送信を実行するという意味です。つまりdsのsrc属性にあるURLにアクセスして、返ってきた結果をデータセットdsに格納します。dsを参照しているコンポーネントはその時点で自身のデータが更新されることになります。

(2) this.setAttribute('text',"更新");は<button>のtext属性値を「更新に」設定します。

(3) showLeft.doStart();はshowLeftという名前の<animator>を開始する、という意味です。

アニメーション

リスト2

<animator id="showLeft" start="false" attribute="x" to="0" duration="300" onstop="parent.setAttribute('align','left');"/>
<animator id="showRight" start="false" attribute="x" to="${-canvas.width}" duration="300" onstop="parent.setAttribute('align','right')"/>

リスト2はアニメーション効果用の<animator>で、左画面を表示するshowLeftと右画面を表示するshowRightの2つです。名前は適当にidでつけています。

start="false"はアプリの起動時に自動開始しない、という意味です。この場合、<animator>のメソッドdoStart()で明示的に開始します。

attributeは何を動かすかという設定で、ここではx座標です。

toは変化後の値です。to="${-canvas.width}" というのは、ブラウザ幅と同じ距離だけ左(attribute="x"なので)に移動です。スライドドアのような効果になります。

durationはアニメーションを動作させている時間で、単位はミリ秒です。

onstopは<animator>のイベントハンドラで、アニメーションの動作が停止したときに実行されるスクリプトを記述します。ここではonstopでalignをleftあるいはrightに設定しています。

左画面(サムネイル画像一覧)

ラッピングレイアウト

リスト3
<wrappinglayout spacing="0"/>

<wrappinglayout>はコンポーネントを格子状に均等配置するレイアウトタグです。特にiPhoneのように画面が縦長か横長かという変わり方をする場合に便利です。

サムネイル画像

リスト4
<twitpic_mini datapath="ds:/feed/entry" >
  <handler name="ondata">
    var tweet = this.datapath.xpathQuery('content/text()'); //(1)
    var start = tweet.indexOf("http://twitpic.com/"); //(2)
    var url = "http://twitpic.com/show/mini" + tweet.substring(Number(start)+18,Number(start)+25); //(3)
    this.setAttribute('src',url); //(4)
  </handler>
  <handler name="onclick">
    showRight.doStart(); //(5)
    btn.setAttribute('text',"戻る"); //(6)
    rightview.datapath.setFromPointer(this.datapath); //(7)
    img.setAttribute('src',this.src); //(8)
  </handler>
</twitpic_mini>

<twitpic_mini>は1つのサムネイル画像を表示するための設定をひとまとめにした自作クラスです。ようは自作のタグですね。datapathを設定しているので、データがあるだけ同じ内容でコピー(=レプリケーション)されて画面に表示されます。ds:/feed/entryにあたるデータが32個あれば、<twitpic_mini>を32個ソースに記述したのと同じことになります。

ondataとonclickの2つのイベントハンドラが設定されています。ondataはdatapathからのデータ取得時、onclickはクリック時の実行スクリプトをそれぞれ記述します。

(1)<twitpic_mini>のdatapathでds:/feed/entryが設定されているので、xpathQuery('content/text()')の指定は、ds:/feed/entry/content/text()になります。text()メソッドでツイートを取り出しています。

(2)(3)取り出したツイート文字列からtwitpicのURLだけを抜き出して変数urlに格納しています。

(4)さらにそのurl値を<twitpic_mini>のsrc属性に設定することで、twitpicの画像を表示しています。

(5)<animator>のshowRightを開始します。右画面が現れます。

(6)ボタンbtnの文字列を「戻る」に変更します。

(7)setFromPointer()はdatapathのメソッドで、他のビューのデータパスに自身のデータパスをコピーできます。この仕組みを使って、サムネイル画像をクリックするとそのサムネイル画像が持つデータパスをrightviewビューに引き継がせることになります。

(8)imgのsrc属性に自身のsrc属性値を設定します。

右画面(画像拡大、ツイート)

右画面

リスト5
<!--右画面(画像拡大、ツイート)-->
<vbox id="rightview" width="${parent.width/2}" datapath="" spacing="2">
・・・
</vbox>

rightviewというidを付けています。幅は親ビュー幅の半分で、ちょうど画面幅です。datapathありきのビューですが、サムネイル画像をクリックするまではデータパスは空なので空白です。<vbox>なので、子ビューを縦に均等配置します。配置間隔はspacingで2ピクセルです。

画像表示

リスト6
<image id="img" align="center" width="${canvas.height/1.7}" height="${this.width}" stretches="both"/>

画像を表示する<image>タグです。画像がブラウザ画面内にうまく表示されるように、幅はとりあえずブラウザ画面の高さの1.7分の1にしています。heightはthis.width、 stretches="both"なので、正方形の画像になります。

クリックイベントハンドラ

リスト7
<text datapath="author/name/text()" fontstyle="bold" fgcolor="blue" textdecoration="underline">
  <handler name="onclick">
    var url = this.datapath.xpathQuery('../uri/text()'); //(1)
    lz.Browser.loadURL(url,'_blank');  //(2)
  </handler>

この<text>ではdatapathで取得できるアカウント名を文字列として表示します。リンクというのが分かりやすいように青文字および下線を指定しています。

名前をクリックしたらその人のURLを開けられるようにonclickハンドラ内にスクリプトを記述しています。

(1)xpathQuery()で、⁠../uri/text()」という指定をしているのは、author/uri/text()のことです。datapath="author/name/text()"でXML構造上では既にauthor/name/の位置にいるので、1つ上に上がってuriに移動しています。この相対的な位置指定は、ファイルシステムのディレクトリ指定と同じ要領です。author/uri/text()では該当アカウントのURLを取得できます。

(2)lz.Browser.loadURL()メソッドは、アンカーテキストの動きと同じで、指定したURLにブラウザレベルで移動するためのメソッドです。

ツイート文字列

リスト8
<text datapath="content/text()" multiline="true" width="${parent.width}"/>

ツイート文字列です。<text>はデフォルト1行表示なので、multiline="true"にして複数行で表示できるようにしています。

お礼

今回でOpenLaszloの連載を終了します。この連載記事がOpenLaszloでマルチデバイス対応アプリを開発する際のとっかかりとして少しでもお役に立てれば幸いです。ありがとうございました。

おすすめ記事

記事・ニュース一覧