7.1创建自己的渲染器

7.1.1.问题
你想要为List 或DataGrid 建item renderers 。
7.1.2.解决办法
你可以定义一个item renderer 在MXML 的List 组件内部。或定义在另一个类文件中,再把这个类名指定在List 的itemRenderer 属性里。
7.1.3.讨论
有很多办法可以创建item renderers 最简单的办法是:作为itemRenderer 属性定义在父组件的内部:
+展开
-XML
<mx:List dataProvider="{simpleArray}">
<mx:itemRenderer>
<mx:Component>
<mx:Label color="#007700"/>
</mx:Component>
</mx:itemRenderer>
</mx:List>

Flex 会为List 的数据源(类型可能是数组或类似数组的数据类型)中的每个元素实例化一个itemRenderer 组件(事实是,只为显示的数据创建itemRenderer),并且会把数据源中对应的元素赋与itemRenderer 的data 属性。上边的例子我们使用了Label 组件,虽然我们没有设置Label 的text 属性,但依然有显示,是因为父组件会把对应的元素传给Label 的data属性,Label 会默认显示data 的值。所以List 的数据源中的每一个元素最好是简单的String类型。如果一个复杂的对象或其他类型的数据传递给Label,你在结果中会看到:[Object
object]。

如果一定要使用一个复杂类型,你最好自己写一个新的item renderer 并且重写他的setdata 方法。例如:
+展开
-XML
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxmlheight="800">
<mx:Script>
<![CDATA[
[Bindable
]
private var simpleArray:Array = new Array("one""two","three""four""five");

]]>
</mx:Script>
<!-- this list can use an inline item renderer because the
array that the List is
using as a dataprovider consists
of simple object 
-->

<mx:List dataProvider="{simpleArray}">
<mx:itemRenderer>
<mx:Component>
<mx:Label color="#007700"/>
</mx:Component>
</mx:itemRenderer>
</mx:List>
<!-- the list component here requires a custom renderer
because we're passing any
object to it, which
means that the renderer will need to know how to handle
each field in the
item 
-->

<mx:List itemRenderer="oreilly.cookbook.SevenOneRenderer"
dataProvider="{DataHolder.genericCollectionOne}"/>

<!-- here we can use a proper drop in item renderer because
the DataGrid handles
each field in the Object
separately 
-->

<mx:DataGrid dataProvider="{DataHolder.genericCollectionOne}">
<mx:columns>
<mx:DataGridColumn dataField="name"/>
<mx:DataGridColumn dataField="age"/>
<mx:DataGridColumn dataField="appearancewidth="200">
<mx:itemRenderer>
<mx:Component>
<!-- note that any component placed here must
extend
IDataRenderer and have a data property that properly displays any
data passed to the data
setter method 
-->

<!- 原文这里容易让人误解,其实把这里的and 换成or 就对了,因为这里的组件不
extend IDataRenderer也可以,只要它有data属性就可以。-->

<mx:TextArea/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:VBox>

如果是复杂的数据,您需要创建一个自定义的renderer,flex 没有组件可以通过内置一个Component 标签来处理像data 这样的复杂数据。不过这并不是个问题,因为我们通常在处理这种需求时使用DataGrid,DataGrid 为每个列对象单独指定renderer,每个renderer 又用于处理data 中的一个属性。但这种方式并不是满足所有情况,有些场合我们并不能使用DataGrid,所以在使用DataGrid 以外组件时为了处理好这些拥有多种类型属性的数据对象,你需要写data 的set 方法并且去处理传入对象的每个属性。大家请看下边的代码,在set data方法里,将data 中感兴趣的属性取出来,并传到Label 里,即使data 中没有某个属性值,
这种方法也是可以工作的。
+展开
-ActionScript
package oreilly.cookbook
{
import mx.containers.HBox;
import mx.controls.Label;
import mx.core.IDataRenderer;
public class SevenOneRenderer extends HBox {
private var nameLabel:Label;
private var ageLabel:Label;
private var appearanceLabel:Label;
private var _data:Object;
public function SevenOneRenderer() {
super();
}
override public function get data():Object {
if (_data != null ) {
return _data;
}
return null
;
}
override public function set data(value:Object):void {
 _data = value; 
if (_data.name != null  ) {
nameLabel = instantiateNewLabel(_data.name);
}
if (_data.age != null ) {
ageLabel = instantiateNewLabel(_data.age);
}
if (_data.appearance != null ) {
appearanceLabel = instantiateNewLabel(_data.appearance);
}
setStyle("backgroundColor", 0xddddff);
}
private function instantiateNewLabel(value:*):Label {
var label:Label = new Label();
label.text = String(value);
addChild(label);
return label;
}
}
}

加支付宝好友偷能量挖...


评论(0)网络
阅读(121)喜欢(0)flash/flex/fcs/AIR