3 August 2011
ページ ツール |
このマスターシリーズでは、Flash Builder 4.5およびAdobe AIRを使用したFlexモバイルアプリケーションの開発について解説します。
本記事では、FlexモバイルプロジェクトのListクラスで使用される「アイテムレンダラークラス」について紹介します。なお、Flash Builder 4.5.1にバンドルされている標準のFlex SDK(バージョン 4.5.1.21328)を対象にしています。
アイテムレンダラークラスにはいくつかありますが、モバイル版Flexアプリケーションでも使用が推奨されているアイテムレンダラークラスは次の2種類です。他の種類のアイテムレンダラークラスは、パフォーマンスの観点から非推奨となっています。
それぞれについて解説していきます。
LabelItemRendererは、Listクラスが標準で使用しているアイテムレンダラークラスです。このクラスは、TextFieldのサブクラスであるStyleableTextFieldを保持しており、ListクラスのlabelFieldプロパティやlabelFunctionプロパティによって定義される1行テキストを表示するだけのシンプルな機能を持ったコンポーネントです。
次のコードは、LabelItemRendererのシンプルなサンプルです(サンプル:LabelItemRendererSample.fxp)
ソースコード:LabelItemRendererSample/src/views/LabelItemRendererSampleMainView.mxml
<?xml version="1.0" encoding="utf-8"?>
<!---
LabelItemRendererSampleMainView.mxml は、LabelItemRenderer のサンプルです。
@author taiga
-->
<s:View
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
title = "LabelItemRenderer Sample"
>
<!--
NOTE:<s:List width="100%" height="100%"> と同義
-->
<s:List width="100%" height="100%"
itemRenderer="spark.components.LabelItemRenderer">
<s:dataProvider>
<s:ArrayList>
<fx:Object data="0" label="aaaaaaa" />
<fx:Object data="1" label="bbbbbbb" />
<fx:Object data="2" label="ccccccc" />
<fx:Object data="3" label="ddddddd" />
<fx:Object data="4" label="eeeeeee" />
<fx:Object data="5" label="fffffff" />
</s:ArrayList>
</s:dataProvider>
</s:List>
</s:View>
IconItemRendererは、下記4点のパーツを兼ね備えたアイテムレンダラークラスです。前述のLabelItemRendererクラスを継承しています。
いずれのパーツもオプションパーツとして用意されているため、全ての項目を使用せずともレンダラーとして機能します。全てのオプションパーツを使用したときの外観は下図の通りです。
次のコードは、IconItemRendererのシンプルなサンプルです(サンプル:IconItemRendererSample.fxp)。
ソースコード:IconItemRendererSample/src/(default package)/IconItemRendererSample.mxml
<?xml version="1.0" encoding="utf-8"?>
<!---
IconItemRendererSample.mxml
@author taiga
-->
<s:ViewNavigatorApplication
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
firstView = "views.IconItemRendererSampleMainView"
>
<fx:Style>
.rendererLabel {
fontSize: 15;
color: #0000FF;
}
</fx:Style>
</s:ViewNavigatorApplication>
ソースコード:IconItemRendererSample/src/views/IconItemRendererSampleMainView.mxml
<?xml version="1.0" encoding="utf-8"?>
<!---
IconItemRendererSampleMainView.mxml は、IconItemRenderer のサンプルです。
@author taiga
-->
<s:View
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
title = "ADC Writers"
>
<s:List width="100%" height="100%">
<s:itemRenderer>
<fx:Component>
<s:IconItemRenderer
messageStyleName = "rendererLabel"
fontSize = "25"
iconField = "photo"
labelField = "firstName"
messageField = "lastName"
decorator = "@Embed(source='assets/images/decorator.png')"
/>
</fx:Component>
</s:itemRenderer>
<s:ArrayCollection>
<fx:Object
firstName = "Taiga"
lastName = "Hirohata"
company = "taiga.jp"
phone = "XXX-XXX-XXX"
photo = "@Embed(source='assets/icon/taiga.jpg')"
/>
<fx:Object
firstName = "Eiichi"
lastName = "Arikawa"
company = "AKABANA"
phone = "YYY-YYY-YYY"
photo = "@Embed(source='assets/icon/eiichi.jpg')"
/>
<fx:Object
firstName = "Toshimitsu"
lastName = "Takahashi"
company = "tilfin"
phone = "ZZZ-ZZZ-ZZZ"
photo = "@Embed(source='assets/icon/toshimitsu.jpg')"
/>
</s:ArrayCollection>
</s:List>
</s:View>
アイテムレンダラーをカスタマイズする場合、PC版Flex 4.x系アプリケーションではGroupクラスを継承したItemRendererクラスを継承してカスタマイズすることが常套手段ですが、モバイル版では前節で紹介したUIComponentクラスを継承したLabelItemRendererクラスや、IconItemRendererクラスを継承してアイテムレンダラークラスをカスタマイズします。
※従来のItemRendererクラスを継承した手法も使用することはできますが、パフォーマンスの観点から非推奨となっています。
Flash Builderでは、カスタムアイテムレンダラークラスを作成するとき、[新規アイテムレンダラー]ダイアログによって、いずれかのアイテムレンダラーを選択できるようになっています。[新規アイテムレンダラー]ダイアログは、メニューの[ファイル]→[新規]→[アイテムレンダラー]を選ぶか、MXMLエディタのコード補間時に表示されるコードヒント内の[アイテムレンダラー]を選ぶことで表示されます。
[新規アイテムレンダラー]ダイアログの[テンプレート]項目で、[モバイルリスト用のカスタムActionScriptアイテムレンダラー(ActionScript)]を選ぶとLabelItemRenderer継承向けのダイアログ内容になり、[モバイルリストのアイコンアイテムレンダラー(MXML)]を選ぶとIconItemRenderer継承向けのダイアログ内容になります。
「新規アイテムレンダラー」ダイアログを利用して、アイテムレンダラーを作成するとき、LabelItemRendererをテンプレートするとActionScriptコードが用意され、IconItemRendererをテンプレートにするとMXMLコードが用意されます。しかし、カスタマイズするときには、いずれもActionScriptコードで作成することを筆者は推奨します(つまり、IconItemRendererをカスタマイズする際は、このダイアログを使わずに自前でIconItemRendererのサブクラスを作成する方がいいでしょう)。
その理由としては、記事冒頭でも解説した通り、いずれのアイテムレンダラーもGroupコンポーネントクラスを継承していないため、VerticalLayoutクラスやHorizontalLayoutクラスなどのレイアウトクラスが使用できず、全て自前でレイアウト処理を実装する必要があり、MXMLで記述するメリットがほとんど存在しないからです。
次のメソッドは、LabelItemRendererクラスを継承したときに、オーバーライドできる主なプロパティとメソッドの一覧です。下表のメソッドは、[新規アイテムレンダラー]ダイアログを使用したとき、自動的に用意されます。
| プロパティ/メソッド | 概要 | |
|---|---|---|
| function set data(value:Object):void | データの変更に応答するときに使用するプロパティです。 | |
| function createChildren():void | アイテムレンダラーの子オブジェクトを作成する、または作成直後の子オブジェクトに対して設定するときに使用するメソッドです。 | |
| function measure():void | アイテムレンダラー自身によるサイズ設定方法を変更するときに使用するメソッドです。 | |
| function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void | アイテムレンダラーの背景の描画方法を変更するときに使用するメソッドです。このメソッドを使用する際、super.drawBackground()は必要な場合だけに実行することが推奨されています。 | |
| function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void | アイテムレンダラーの子要素のサイズ、位置を設定する方法を変更するときに使用するメソッドです。このメソッドを使用する際、super.layoutContents()は必要な場合だけに実行することが推奨されています。 | |
これらのプロパティとメソッドは、LabelItemRendererクラスだけでなく、IconItemRendererクラスでも使用できます。
次のコードは、LabelItemRendererクラスを継承したアイテムレンダラークラスを使用したサンプルです(サンプル:CustomLabelItemRendererSample.fxp)。本来、1行表示機能のラベルを複数行表示するように修正して、さらにレンダラーの背景色をコードで変更するカスタマイズ機能を実装しています。
ソースコード:CustomLabelItemRendererSample/src/views/CustomLabelItemRendererSampleMainView.mxml
<?xml version="1.0" encoding="utf-8"?>
<!---
CustomLabelItemRendererSampleMainView.mxml は、
カスタム LabelItemRenderer のサンプルです。
@author taiga
-->
<s:View
xmlns:fx = "http://ns.adobe.com/mxml/2009"
xmlns:s = "library://ns.adobe.com/flex/spark"
title = "Custom LabelItemRenderer Sample"
>
<s:List width="100%" height="100%"
itemRenderer="com.adobe.sample.CustomLabelItemRenderer">
<s:dataProvider>
<s:ArrayList>
<fx:Object data="0" label="aaaa
aaa" />
<fx:Object data="1" label="bb
bb
bbb" />
<fx:Object data="2" label="ccccccc" />
<fx:Object data="3" label="ddddddd" />
<fx:Object data="4" label="eeeeeee" />
<fx:Object data="5" label="fff
ffff" />
</s:ArrayList>
</s:dataProvider>
</s:List>
</s:View>
ソースコード:CustomLabelItemRendererSample/src/com.adobe.sample/CustomLabelItemRenderer.as
package com.adobe.sample {
import flash.display.Graphics;
import spark.components.LabelItemRenderer;
/**
* CustomLabelItemRenderer は、LabelItemRenderer のカスタマイズクラスです。
* @author taiga
*/
public class CustomLabelItemRenderer extends LabelItemRenderer {
/**
* コンストラクタ
*/
public function CustomLabelItemRenderer() {
super();
}
/**
* @private
* データの変更に応答するには、この setter をオーバーライドします
*/
public override function set data(value:Object):void {
super.data = value;
}
/**
* @private
* アイテムレンダラーの子を作成するには、このメソッドをオーバーライドします
*/
protected override function createChildren():void {
super.createChildren();
if(labelDisplay != null) {
labelDisplay.multiline = true;
labelDisplay.wordWrap = true;
}
}
/**
* @private
* アイテムレンダラー自身によるサイズ設定方法を変更するには、
* このメソッドをオーバーライドします。パフォーマンスに影響するため、
* 必要がない場合は super.measure() を呼び出さないでください。
*/
protected override function measure():void {
super.measure();
}
/**
* @private
* アイテムレンダラーの背景の描画方法を変更するには、このメソッドを
* オーバーライドします。パフォーマンスに影響するため、必要がない場合は
* super.drawBackground() を呼び出さないでください。
*/
protected override function drawBackground(unscaledWidth:Number,
unscaledHeight:Number):void {
var g:Graphics = graphics;
var backgroundColor :uint;
if(down) {
backgroundColor = 0x999999;
}
else if(showsCaret) {
backgroundColor = 0xcc3333;
}
else {
backgroundColor = 0xcccccc;
}
g.clear();
g.beginFill(0x666666);
g.drawRoundRectComplex(5, 5, unscaledWidth - 10,
unscaledHeight - 10, 10, 10, 10, 10);
g.endFill();
g.beginFill(backgroundColor);
g.drawRoundRectComplex(6, 6, unscaledWidth - 12,
unscaledHeight - 12, 9, 9, 9, 9);
g.endFill();
}
/**
* @private
* このアイテムレンダラーの背景の描画方法を変更するには、このメソッドを
* オーバーライドします。パフォーマンスに影響するため、必要がない場合は
* super.layoutContents() を呼び出さないでください。
*/
protected override function layoutContents(unscaledWidth:Number,
unscaledHeight:Number):void {
super.layoutContents(unscaledWidth, unscaledHeight);
}
}
}
IconItemRendererクラスに標準で実装されている機能の中に、画像キャッシュ機能があります。この機能は、iconFieldプロパティで定義したオブジェクトプロパティの画像データ値がURLRequestオブジェクトのような外部リソースの場合、画像を表示するたびにリクエスト処理を実行させないように画像データをキャッシュします(標準で、最大100件分の画像データをキャッシュするように設定されています)。
もし、この機能を無効化したい、あるいはキャッシュ数を変更したい場合は、IconItemRendererクラスを継承したクラスを作成して、ContentCacheインスタンスに変更処理を加える必要があります。
次のコードは、最大キャッシュ件数を減らして、画像読み込みキューイング機能を無効化したIconItemRenderer継承クラスです。
CustomIconItemRenderer.as
package com.adobe.sample.renderer {
import mx.core.mx_internal;
import spark.components.IconItemRenderer;
import spark.core.ContentCache;
use namespace mx_internal;
/**
* CustomIconItemRenderer クラスは、ContentCache インスタンス値を修正した IconItemRenderer サブクラスです。
* @author taiga
*/
public class CustomIconItemRenderer extends IconItemRenderer {
/**
* コンストラクタ
*/
public function CustomIconItemRenderer() {
if (_imageCache == null) {
_imageCache = new ContentCache();
_imageCache.enableQueueing = false;
_imageCache.maxCacheEntries = 50;
}
super();
}
}
}
以上がFlexモバイルアイテムレンダラーについての基本的な項目の紹介でした。PC版Flex 4.x系アプリケーションと比べて、モバイル版Flex 4.x系アプリケーションでは、高度なレンダラーカスタマイズ知識が求められることに気付けたかと思います。
これらのチュートリアルを確認し、Flexモバイルアプリケーションのアイテムレンダラーの構造を知ることによって、実際にアプリケーション開発に携わるとき、より現実的な設計を行うことができるでしょう。