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

第5回LZXによるレイアウトその2]

前回の記事ではタグごとの属性値(x、y、alignなど)で配置位置を決めていましたが、今回はLZXに標準で提供されている自動配置用のタグを紹介します。

自動配置用タグ

<simplelayout>

<simplelayout>を使うと、兄弟ビュー(ソースのXML構造でいう同一階層にあるビュー)を縦や横方向に等間隔で配置することができます。デフォルトは縦方向です。

リスト1 縦方向に自動配置
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout/>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</canvas>

リスト1サンプル

axis属性で方向を指定します。値はxあるいはyです。デフォルトはyです。axis="x"にすると横方向になります。

リスト2 横方向に自動配置
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout axis="x"/>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</canvas>

リスト2のサンプル

spacing属性で間隔を指定できます。単位はピクセルです。

リスト3 横方向に10ピクセル間隔で自動配置
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout spacing="10" axis="x"/>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</canvas>

リスト3のサンプル

縦と横の<simplelayout>を2つ使うと斜め方向になります。

リスト4 縦横方向に等間隔で自動配置
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout spacing="5"/>
  <simplelayout spacing="10" axis="x"/>
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button>4</button>
  <button>5</button>
</canvas>

リスト4のサンプル

<wrappinglayout>

<wrappinglayout>は格子状にビューを自動配置します。大きさを自由に変更できるウインドウや、iPhoneなど縦横に表示を切り替えられるデバイスに便利な機能です。

リスト5のサンプルのウインドウのサイズを変えてみてください。

リスト5 格子状に自動配置
<canvas proxied="false" bgcolor="0xffffcc">
  <window width="250" height="100" resizable="true">
    <wrappinglayout spacing="5"/>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <button>6</button>
    <button>7</button>
    <button>8</button>
    <button>9</button>
  </window>
</canvas>

リスト5のサンプル

<reverselayout>

ソースに書いた順番と逆向きに自動配置するタグです。<simplelayout>での向きを逆にしたものです。

リスト6 逆向きに配置
<canvas proxied="false" bgcolor="0xffffcc">
  <reverselayout/>
  <button>1</button>
  <button>2</button>
  <button>3</button>
</canvas>

リスト6のサンプル

<stableborderlayout>

3つのビューのサイズについて、両端の2つを固定サイズ、真ん中は残り全部、というレイアウト機能を提供するタグです。真ん中のビューの幅は自動的に「全体の幅」「両サイドの幅」となります。

サンプルでは両サイドの青いビューの幅は固定ですが、真ん中の黄色いビューの幅は残り全部になっています。

リスト7 両サイド幅固定レイアウト
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout spacing="10"/>
  <view width="250" height="100">
    <stableborderlayout axis="x"/>
    <view bgcolor="blue" width="30" height="100" /><!--固定幅-->
    <view bgcolor="yellow" height="100" /><!--幅は自動的に残り全部-->
    <view bgcolor="blue" width="30" height="100" /><!--固定幅-->
  </view>
  <view width="100" height="100" >
    <stableborderlayout axis="x"/>
    <view bgcolor="blue" width="30" height="100" /><!--固定幅-->
    <view bgcolor="yellow" height="100" /><!--幅は自動的に残り全部-->
    <view bgcolor="blue" width="30" height="100" /><!--固定幅-->
  </view>
</canvas>

リスト7のサンプル

<constantlayout>

<constantlayout>を使うと上または左の余白(padding)が設定できます。兄弟タグに対して作用します。

リスト8 左側に20ピクセルの余白を設定
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout axis="y" spacing="10"/>
  <constantlayout axis="x" value="20"/>
  <view bgcolor="red" width="40" height="15"/>
  <view bgcolor="aqua" width="50" height="15"/>
  <view bgcolor="yellow" width="60" height="15"/>
  <view bgcolor="green" width="20" height="15"/>
</canvas>

リスト8のサンプル

<resizelayout>

<resizelayout>は複数のビューのうち固定サイズのものとそれ以外にわけることができます。サイズを指定しないビューは、⁠全体サイズ⁠⁠-⁠固定サイズ合計」のサイズを等分割して割り当てられます。 <stableborderlayout>と似ていますが、<stableborderlayout>はビュー3個限定なのに対して、<resizelayout>は4個以上のビューを扱えるところが違います。<stableborderlayout>は<resizelayout>の機能限定版といった感じです。

サイズを指定しないビューには、options="releasetolayout"という属性を指定します。

リスト9のサンプルは青いビューが左から30ピクセル、60ピクセル、90ピクセルの固定幅で、2つの黄色いビューは残りの幅を二等分されています。

リスト9 固定幅,可変幅のビューの混在レイアウト
<canvas proxied="false" bgcolor="0xffffcc">
  <view width="400">
    <resizelayout axis="x"/>
    <view bgcolor="blue" width="30" height="100"/>
    <view bgcolor="yellow" height="100" options="releasetolayout"/>
    <view bgcolor="blue" width="60" height="100"/>
    <view bgcolor="yellow" height="100" options="releasetolayout"/>
    <view bgcolor="blue" width="90" height="100"/>
  </view>
</canvas>

リスト9のサンプル

<hbox>,<vbox>

単純に縦や横に並べるだけなら、<view>と<simplelayout>の機能をくっつけた<hbox>,<vbox>がお手軽です。<hbox>は<view>の中に<simplelayout axis="x">,<vbox>は<simplelayout axis="y">を入れたのと同じ動作をします。間隔はspacingで指定できます。

リスト10 <hbox>,<vbox>
<canvas proxied="false" bgcolor="0xffffcc">
  <vbox spacing="20">
    <hbox spacing="10">
      <button>1</button>
      <button>2</button>
      <button>3</button>
      <button>4</button>
      <button>5</button>
    </hbox>
    <vbox spacing="10">
      <button>6</button>
      <button>7</button>
      <button>8</button>
      <button>9</button>
      <button>10</button>
    </vbox>
  </vbox>
</canvas>

リスト10サンプル

ignorelayout

<simplelayout>などのレイアウトタグがあると、同一階層内のビュー(兄弟ビュー)はすべてその影響を受けて自動配置されます。特定のビューだけその影響を受けないで好きな位置に配置したい場合は、そのビューにoptions="ignorelayout"をつけます。

サンプルで、ボタン3にx="100"とy="20"を指定していますが、上部(緑のビュー)は縦方向にレイアウト機能が働いていますので、y="20"の指定は無視されます。一方、下部(青のビュー)はoptions="ignorelayout"を指定しているので、自動レイアウトの対象から外れ、y="20"の位置に個別に配置されています。緑ビューと青ビューの両方とも横方向への自動レイアウト機能は設定されてないのでx="100"の指定は有効です。

リスト11 レイアウト機能の無視
<canvas proxied="false" bgcolor="0xffffcc">
  <vbox spacing="20">
    <vbox spacing="2" bgcolor="green">
      <button>1</button>
      <button>2</button>
      <button x="100" y="20" >3</button>
      <button>4</button>
      <button>5</button>
    </vbox>
    <vbox spacing="2" bgcolor="blue">
      <button>1</button>
      <button>2</button>
      <button x="100" y="20" options="ignorelayout">3</button>
      <button>4</button>
      <button>5</button>
    </vbox>
  </vbox>
</canvas>

リスト11サンプル

オフセット配置

xoffset、yoffset属性を使うとx軸やy軸の表示位置をずらすことができます。x属性とy属性は元のままで、表示位置だけがずれていることになります。

サンプルでいうと、ボタン3は本来の位置から左に15ピクセル(xoffset="15")、上に10ピクセル(yoffset="10")ずれた場所に表示されています。ボタンの本来の位置と表示位置が異なる、というのをサンプルで確認してみましょう。リスト12のサンプル上で1回クリックしてからTABキーを押すとフォーカス移動と同時にフォーカス枠が出現します。フォーカス枠は本来の位置に来ますのでそれで確認できます。試してみてください。

リスト12 オフセット配置
<canvas proxied="false" bgcolor="0xffffcc">
  <vbox spacing="2" x="20">
    <button>1</button>
    <button>2</button>
    <button xoffset="15" yoffset="10" >3</button>
    <button>4</button>
    <button>5</button>
  </vbox>

リスト12サンプル

コンストレイント

コンストレイントはLZXの強力な機能の1つで、自分や他のビューの属性値を自身の属性値に連動させることができます。これを使いこなせるようになるとレイアウトの構築やメンテナンスがだいぶ楽になります。といってもわかりにくいので早速サンプルで試してみましょう。

使用例1

コンストレイントの書式は${・}で、中に式を書きます。height="${this.width}" のように属性値として指定できます。

サンプル13の例では、1つ目の赤いビューは幅を数値で指定していますが、高さは${this.width}になっています。これは高さを幅と同じにするという意味で、つまり正方形を作ることができます。

2つ目の${this.width*2}は幅の2倍、3つ目の${this.width/2}は幅の半分の数値をそれぞれ表します。

リスト13 幅と高さの連動
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout spacing="5" axis="x"/>
  <view width="50" height="${this.width}" bgcolor="red"/>
  <view width="50" height="${this.width*2}" bgcolor="red"/>
  <view width="50" height="${this.width/2}" bgcolor="red"/>

リスト13サンプル

使用例2

スライダーの値をビューの幅に連動させた例です。<slider>を動かすとその値がvalueという属性にセットされます。その値を赤いビューの幅の値(width="${sl.value*2}")として取り込んでいます。

リスト14 スライダーの値と幅の連動
<canvas proxied="false" bgcolor="0xffffcc">
  <simplelayout spacing="20"/>
  <view width="${sl.value*2}" height="50" bgcolor="red"/>
  <slider id="sl" minvalue="10" maxvalue="100" />
</canvas>

リスト14サンプル

使用例3

スライダーの値をビューのx属性に連動させた例です。x="${parent.width-sl.value}"は、1つ上の階層のビューの幅(parent.width)から、スライダーの値(sl.value)を引いた値をx属性の値として連動させています。ようするにスライダーと逆方向に動きます。

リスト15 スライダーの値とxの連動
<canvas proxied="false" bgcolor="0xffffcc">
  <vbox width="100" spacing="20">
    <view x="${parent.width-sl.value}" width="10" height="10" bgcolor="red"/>
    <slider id="sl" minvalue="10" maxvalue="100" />
  </vbox>
</canvas>

リスト15サンプル

使用例4

ウインドウを動かしたりサイズを変更すると、赤い四角の大きさや縦方向の位置が変わります。

リスト16 幅、高さ、y属性の連動
<canvas proxied="false" bgcolor="0xffffcc">
  <vbox y="${win.y}" width="${win.width}" height="${this.width}" bgcolor="red"/>
  <window id="win" x="50" width="100" height="100" resizable="true"/>
</canvas>

リスト16サンプル

レイアウト例

これまでに解説したテクニックを使って,Webサイトでよくある画面のレイアウトを2つほど構築してみます。

ログイン画面

簡単なログイン画面を作ってみます。文字は<text>、入力欄は<edittext>、ボタンは<button>を使います。

リスト17 ログイン画面
<canvas proxied="false" bgcolor="0xffffcc">
  <!-- (1) -->
  <view width="200" height="150" bgcolor="teal">
    <!-- (2) -->
    <view width="${parent.width-4}" height="${parent.height-4}" align="center" valign="middle" bgcolor="silver">
      <!-- (3) -->
      <vbox y="10" align="center" >
        <text>ログイン</text>
        <edittext/>
        <text>パスワード</text>
        <edittext password="true"/>
        <view height="10"/><!-- (4) -->
        <button>ログイン</button>
      </vbox>
    </view>
  </view>
</canvas>

リスト17サンプル

リスト17を解説します。(1)はログインボックス全体のエリア用のビューです。

(2)は幅、高さとも親ビューより4ピクセル少ないビューで、alignとvalignで中央に配置しているので、まわりに2ピクセル幅の枠線が出ることになります。このように大きい四角の中に小さい四角を入れるとボーダー付きの四角ができあがります。

(3)は文字列や入力欄などの部品を入れるビューです。<vbox>なのでタグ内の部品は縦に自動配置します。

(4)の<view height="10"/>とは高さ10ピクセルの透明のエリアです。入力欄とボタンの間隔をあけるためだけに配置しました。 このようにすると自動レイアウトの機能をそのまま使いつつ、位置を調整することができます。

コンテンツ画面

業務アプリやホームページなどでよく見るような画面レイアウトを作ってみます。まず、上段、中段、下段のビューを縦に並べます。中段はさらに横方向に左サイド、コンテンツエリア、右サイド、というふうに並べます。属性の値はコンストレイントを使ってうまく連動させるようにします。

リスト18 画面レイアウト
<canvas proxied="false" bgcolor="0xffffcc">
  <stableborderlayout axis="y"/>
  <!-- (1)上段 -->
  <view width="${parent.width}" height="50" bgcolor="red">
    <text>ヘッダ</text>
  </view>
  <!-- (2)中段 -->
  <hbox width="${parent.width}">
    <stableborderlayout axis="x"/>
    <!-- (2-1)中段 左 -->
    <vbox width="100" height="${parent.height}" bgcolor="yellow">
      <text>左サイド</text>
    </vbox>
    <!-- (2-2)中段 中 -->
    <vbox height="${parent.height}">
      <text>コンテンツエリア</text>
    </vbox>
    <!-- (2-2)中段 右 -->
    <vbox width="70" height="${parent.height}" bgcolor="yellow">
      <text>右サイド</text>
    </vbox>
  </hbox>
  <!-- (3)下段 -->
  <view width="${parent.width}" height="30" bgcolor="green">
    <text>フッタ</text>
  </view>
</canvas>

リスト18サンプル

おすすめ記事

記事・ニュース一覧