Xml

Flex itemRendererは(2)外部レンダラーを使用します



Flex Itemrenderer Uses External Renderer

このシリーズのパート1では、インラインitemRendererを作成する方法を説明しました。itemRendererのMXMLタグとActionScriptコードは、itemRendererを使用するリストと同じファイルにあります。コードは、ファイル内の残りのコードとインラインになっています。

インラインitemRendererは別のクラスとして扱われるべきだと言ったことを覚えておく必要があります。実際、Flexコンパイラはこれらのインラインコードを抽出し、クラスを作成します。インラインitemRendererの利点は、コードがリストと同じ場所にあることですが、itemRendererが複雑になると、欠点になります。この記事では、自分でクラスを作成する方法を紹介します。

itemRendererを外部ファイルに抽出することにはいくつかの利点があります。

•itemRendererは複数のリストで簡単に使用できます
•コードの保守が容易
•FlexBuilderのデザインビューを使用して、元のitemRendererをドラフトできます。

第1章で説明したように、インラインitemRendererは別のクラスとして扱う必要があります。実際、Flexコンパイラはこれらのインラインコードを抽出し、クラスを作成します。インラインitemRendererの利点は、コードがリストと同じ場所にあることですが、itemRendererが複雑になると、欠点になります。この記事では、自分でクラスを作成する方法を紹介します。

itemRendererを外部ファイルに抽出することにはいくつかの利点があります。
•itemRendererは複数のリストで簡単に使用できます
•コードの保守が容易
•FlexBuilderのデザインビューを使用して、元のitemRendererをドラフトできます。

[color = red] MXML itemRenderer [/ color]

パート1では、DataGridに複雑なitemRendererがあることを確認しました。






override public function set data( value:Object ) : void {
super.data = value
var today:Number = (new Date()).time
var pubDate:Number = Date.parse(data.date)
if( pubDate > today ) setStyle('backgroundColor',0xff99ff)
else setStyle('backgroundColor',0xffffff)
}
]]>









itemRendererはHBoxに基づいており、画像とテキストを含み、プロジェクトレコードのpubDateフィールドに基づいて背景色を設定します。次の手順を使用して、外部ファイルと同じitemRendererを書き込むことができます。


1. Flex Builderを使用している場合は、新しいMXMLコンポーネントファイルを作成し(ファイルにGridColumnSimpleRendererという名前を付けました。好きな名前を付けることができます)、ルートタグをHBoxに設定します。サイズは気にしないでください。
2. SDKのみを使用する場合は、新しいMXMLファイル(GridColumnSimpleRenderer.mxmlという名前)を作成し、ルートタグをHBoxに設定します。
3.ファイルが開いているときに、との間のすべてをコピーしますが、それらのタグはすでにファイルにあるため、コピーしないでください。結果は次のようになります。




override public function set data( value:Object ) : void {
super.data = value
var today:Number = (new Date()).time
var pubDate:Number = Date.parse(data.date)
if( pubDate > today ) setStyle('backgroundColor',0xff99ff)
else setStyle('backgroundColor',0xffffff)
}
]]>







4.このファイルを保存します。
次に、インラインitemRendererを削除し、次のように置き換えて、DataGridColumn定義を変更します。

itemRenderer='GridColumnSimpleRenderer'>

今すぐこのアプリを実行してください。あなたはショックを受けるでしょう。線がとても高いからです。これは、itemRendererにあるためです。

[color = red]は、itemRenderer [/ color]の幅と高さを決定します

Listコントロールは、常にitemRendererの幅を設定します。この場合、明示的なものは無視されます。ユーザーが列を変更するか、リストの幅が変更されると仮定して、独自のitemRendererを作成する必要があります。

高さは別の問題です。リストに明示的なrowHeightが設定されている場合、itemRendererに設定した高さを無視して、各行にこの高さを課します。ただし、リストのvariableRowHeightプロパティをtrueに設定すると、リストはitemRendererの高さを慎重に考慮します。この場合、高さは明示的に300に設定されているため、各動作の高さは300ピクセルです。

これを修正するには、itemRendererファイルから明示的な高さを削除すると、アプリケーションが正しく実行されます。


[color = red] itemRendererを動的に変更[/ color]

この例では、set data()関数をオーバーライドして、データをチェックし、itemRendererのbackgroundColorを設定します。これは非常に一般的です。 set data()をオーバーライドすると、新しい行のデータを変更するのにかかる時間をインターセプトでき、スタイルを変更できます。

よくある間違いは次のとおりです。

•super.data = valueを呼び出すのを忘れました。これは致命的なエラーです-itemRendererを台無しにします。
•スタイルをリセットするのを忘れた(テストが失敗した場合)。 pubDateが将来になると、色を設定したくなるかもしれませんが、itemRendererがリサイクルされることを覚えておく必要があるため、elseステートメントが必要です。


[color = red] ActionScript itemRenderer [/ color]

次に、別のitemRendererを作成します。今回は、ActionScriptクラスを使用します。前回の記事では、このインラインitemRendererを含むTileListがありました。
















var e:BuyBookEvent = new BuyBookEvent()
e.bookData = data
dispatchEvent(e)
]]>










これをActionScriptの外部itemRendererに変換します。次の手順を実行する必要があります。

1.新しいActionScriptクラスを作成します。 BookTileRenderer.asという名前を付け、インラインitemRendererと同じように、HBoxを拡張します。

package
{
import flash.events.MouseEvent

import mx.containers.HBox
import mx.containers.VBox
import mx.controls.Button
import mx.controls.Image
import mx.controls.Label
import mx.controls.Spacer
import mx.controls.Text

public class BookTileRenderer extends HBox
{
public function BookTileRenderer()
{
super()
}

}
}


2.子コンポーネントへの参照を保持するために使用されるメンバー変数を作成します。

private var coverImage:Image
private var titleText:Text
private var spacer1:Spacer
private var authorLabel:Label
private var pubdateLabel:Label
private var spacer2:Spacer
private var buyButton:Button


3. createChildren()関数をオーバーライドして子コンポーネントを作成し、それらをHBoxに追加します。

override protected function createChildren():void
{
coverImage = new Image()
addChild(coverImage)

var innerBox:VBox = new VBox()
innerBox.explicitHeight = 115
innerBox.percentWidth = 100
innerBox.setStyle('verticalAlign','top')
innerBox.setStyle('verticalGap', 0)
addChild(innerBox)

titleText = new Text()
titleText.setStyle('fontWeight','bold')
titleText.percentWidth = 100
innerBox.addChild(titleText)

spacer1 = new Spacer()
spacer1.explicitHeight = 20
innerBox.addChild(spacer1)

authorLabel = new Label()
innerBox.addChild(authorLabel)

pubdateLabel = new Label()
innerBox.addChild(pubdateLabel)

spacer2 = new Spacer()
spacer2.percentHeight = 100
innerBox.addChild(spacer2)

var buttonBox:HBox = new HBox()
buttonBox.percentWidth = 100
buttonBox.setStyle('horizontalAlign','right')
innerBox.addChild(buttonBox)

buyButton = new Button()
buyButton.label = 'Buy'
buyButton.setStyle('fillColors',[0x99ff99,0x99ff99])
buyButton.addEventListener(MouseEvent.CLICK, handleBuyClick)
buttonBox.addChild(buyButton)
}



このコードを使用して、親子関係を示します。また、[購入]ボタンには必ずイベントリスナーを含めてください。

4. commitProperties()関数をオーバーライドし、データからユーザーインターフェイスを制御します。

override protected function commitProperties():void
{
super.commitProperties()

coverImage.source = data.image
titleText.text = data.title
authorLabel.text = data.author
pubdateLabel.text = data.date
}


5. [購入]ボタンのクリックイベントハンドラーを追加します

private function handleBuyClick( event:MouseEvent ) : void
{
var e:BuyBookEvent = new BuyBookEvent()
e.bookData = data
dispatchEvent(e)
}



6.メインアプリケーションのTileListを変更して、itemRendererActionScriptクラスを使用します。 inlineItemRendererを削除し、タグ内のitemRendererプロパティに置き換えるだけです。

dataProvider='{testData.book}' column row >


HBoxなどの既存のコンテナクラスを使用する場合は、ActionScriptを使用しません。 MXMLファイルを使用するよりも複雑であり、正直なところ、パフォーマンスの面でほとんど利点はありません。

[color = red]再利用可能なitemRenderer [/ color]
以下は、CurrencyFormatterを使用して数値を表示するitemRendererの例です。私はそれをPriceFormatterと呼んでいます:





import mx.controls.dataGridClasses.DataGridListData

[Bindable] private var formattedValue:String

override public function set data(value:Object):void
{
super.data = value

formattedValue = cfmt.format( Number(data[(listData as DataGridListData).dataField]) )

}
]]>




{formattedValue}




このitemRendererの重要な部分は赤でマークされ、バインド可能な変数formattedValueを設定します。まず、id cfmtを使用してMXMLタグとして定義されていることがわかります(必要に応じて、ActionScriptを使用してこれを行うこともできます)。上記の例では、formattedValueはCurrentFormatterのformat()関数の呼び出しの結果に設定されています。

この関数は引数タイプとしてNumberを受け取るため、値はNumberに変換されます-これは、リストのdataProviderがXMLであり、データにObjectを使用し、実際の値がある場合、XML内のすべてがテキストであるためです。番号の遷移は有害ではありません。

ご存知のように、データはitemRendererによって表示されるアイテムを保持するプロパティです。 []トークンを使用することは、データ項目フィールドにアクセスするもう1つの方法です。たとえば、data ['price']は価格列です。ただし、このitemRendererを再利用できるようにするには、特定のフィールドをエンコードできないため、より一般的なアプローチが必要です。

この時点で、listDataがデビューします。 IDropInListItemRendererインターフェイスを実装するすべてのFlexコンポーネントには、listDataプロパティがあります。

注:Text、Label、Button、CheckBoxなどのほとんどのコントロールは、IDropInListItemRendererを実装しています。 HBox、Canvasなどのほとんどのコンテナは、このインターフェイスを実装していません。拡張コンテナのitemRendererでlistDataを使用する場合は、IDropInListItemRendererを自分で実装する必要があります。これについては次の記事で説明します。

特に、itemRendererに提供されるlistDataには、rowIndexと、itemRendererを持つコントロール(DataGrid、List、またはTileList)も含まれています。 itemRendererがDataGridで使用される場合、listDataは実際にはDataGridListDataオブジェクトです。これには、DataGridColumnに関連付けられたcolumnIndexとdataFieldが含まれます。以下は、上記のステートメントの内訳です。

•listDataas DataGridListData-listDataをDataGridListDataオブジェクトに変換し、そのdataFieldへのアクセスを提供します
•.dataField-このフィールドは、列をレンダリングするために使用されます。これにより、このitemRendererが汎用になります。このitemRendererは、複数の列に使用できます。この場合、dataFieldは 'price'です。
•data [...]-プロジェクトの特定のフィールドのデータにアクセスします。この場合、それは価格列です。
•number(...)-format()関数にはNumberパラメーターが必要なため、値を数値に変換します。
•cfmt.format(...)-値を通貨としてフォーマットします


itemRendererを実装するときは、好きな言語を使用できます。もちろん、ActionScriptのみを使用する人もいますが、FlexとActionScriptの経験がある場合は、これはすばらしいことです。 MXMLは、単純なitemRendererをすばやく作成することもできます。

パート3で、itemRendererとアプリケーションの残りの部分との間の通信についてさらに説明します。