ItemRender---详细讲解理论篇

今天我们简述一下,Flex里面的哪些组件也具有数据处理能力。

1、dataProvider
     在Adobe ActionScript 3.0里面的定义如下:
    要查看的数据集。此属性允许您将大多数类型的对象用作数据提供程序。如果将 dataProvider属性设置为 Array,则会将其转换为 ArrayCollection。如果将该属性设置为 XML对象,则会将其转换为仅包含一个项目的 XMLListCollection。如果将该属性设置为XMLList,则会将其转换为 XMLListCollection。如果将该属性设置为实现 IList 或 ICollectionView接口的对象,则可直接应用此对象。受转换操作的影响,在您获取 dataProvider属性时,该属性值将始终为 ICollectionView,所以此值不一定是您设置的对象类型。如果要修改数据提供程序中的数据,则了解以下行为非常重要:可能不会检测对原始数据所做的更改,但将检测对从 dataProvider属性获取的 ICollectionView 对象所做的更改。默认值为 null.此属性可用作数据绑定的源。
    上面那一大堆的东西其实就说明以下几点:
    a、凡是具有dataProvider的组件,都可以将Array、XML等内容作为数据源。
    b、将这些作为数据源的内容“自动”绑定并显示在这些控件上面。
    所以通常的做法,当Flex获取了外部数据后,可以将其直接赋值为dataProvider,然后通过一些设定,就可以在这些组件上面显示数据了。

2、itemRenderer(项目渲染器)及其data属性。
     itemRenderer的作用就是可以自定义一些组件的项目显示效果,例如我们熟知的Combobox、List、DataGrid等都具有这样的属性,也就是说,我们可以利用itemRenderer来改善ComBoBox里面的下拉的显示效果。当然,List、DataGrid也是这样的。
     当ComboBox中自定义了一个渲染器后,同时使用dataProvider的方式绑定了一个数据源,这个时候,如何与我们自定义的渲染器里面的item发生作用呢?就是使用data方式。
     也就是说,dataProvider可以绑定数据到UI、如果这个组件使用了自定义渲染器,那么就可以使用data.XXX的方式获取到dataProvider里面的数据。
注意:如果你对itemRenderer很陌生,请记住多数Flex组件,包括用来作为itemRenderer的组件都有一个data属性。这个属性是由dataProvider中与itemRenderer所在行相应的记录所设定的。
okay,以上介绍的两个知识点是关于Flex组件的数据处理能力,其中dataProvider可以把Array、XML等内容作为数据源直接绑定并显示到UI上面,而itemRenderer里面的data是实现组件与其渲染器之间的数据处理,相当于一个管道把组件和渲染器连接起来。


itemRenderer的实现原理

通过上面的例子,不难发现实现自定义itemRenderer的重要前提是:程序能够根据完整的类路径,动态创建类的实例。Flex中,MXML组件的本质即ActionScript类。在上面的例子中,组件位于程序的同一目录中,所以“ProductltemRenderer”就是类的完整路径。这正是ActionScript3.0的一个重要特性:反射机制。

反射(Reflection),是指在程序运行时获取类信息的方式,比如实现动态创建类实例、方法等。和反射机制相关的函数都位于flash.utils包类,下面是一段示例代码:

Class是一个特殊的数据类型,描述类的定义。每一个类都对应一个Class对象,每个Class对象又都是Class类的实例。这听上去有点绕口,都是该类对应的Class的实例。正是反射机制造就了itemRenderer这一强大功能。

itemRenderer工作方式

itemRenderer通过接口和控件要进行数据交互,比如上面用到的data存取器,还,有用于某些特殊场合的IistData存取器。Flex框架中频繁使用了接口,这些做的一个好处是保证了系统伸缩性和低耦合的完美平衡。

所有可以被用来当作itemRenderer的组件,都必须实现规定的接口,其中,位于mx.core包中的IDataRenderer接口是最基础的一个,其代码如下:
官方文档说明如下:


IDataRenderer 接口用于为具有 data 属性的组件定义接口。

系统使用 data 属性将要呈现或编辑的数据传递给以下组件:在 list 控件(如 List、HorizontalList、TileList、DataGrid 和 Tree 控件)中的项目渲染器或项目编辑器中使用的组件,或者用作图表中渲染器的组件。组件必须实现 IDataRenderer,以便主机组件可以传递此信息。所有 Flex 容器和许多 Flex 组件都实现 IDataRenderer 和 data 属性。

在 list 控件中,Flex 将项目渲染器或项目编辑器的 data 属性设置为数据提供程序中对应于正在呈现或编辑的项目的元素。对于 DataGrid 控件,data 属性包含 DataGrid 控件整行的而不仅仅是该项目的数据提供程序元素。

若要实现此接口,需定义 setter 和 getter 方法以实现 data 属性。通常,setter 方法将 data 属性的值写入内部变量并调度 dataChange 事件,而 getter 方法返回内部变量的当前值,如下例所示:
// Internal variable for the property value.
private var _data:Object;

// Make the data property bindable.
[Bindable("dataChange")]

// Define the getter method.
public function get data():Object {
return _data;
}

// Define the setter method, and dispatch an event when the property
// changes to support data binding.
public function set data(value:Object):void {
_data = value;

dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));
}

我们要检验一个对象是否能被当作itemRenderer,只须测试它是否继承了这个接口,可以通过as操作符简单判断:

由于不同控件对数据处理的不同,在此基础上又衍生出其它的接口,来适应不同的需要,包括用于显示简单数据的mx.controls.listClasses.IListltemRenderer;用于处理复杂数据的mx.controls.IistClasses.IDroplnListltemRenderer;专用于Menu组件的mx.controls.menuClasses.IMenultemRenderer等等。

在使用自定义itemRenderer时,有一点必须明白:List系列组件并不是简单地把数据一次显示。为了提高运行效率,组件在处理数据时,只是创建了适当数量的itemRenderer,来完成显示区域的数据显示,这样,当数据源的数据量很大时,不会耗费系统过多的资源。而且,itemRenderer是根据需要创建,创建后被反复使用,很绿色,很环保。当显示区域发生变化或者拉动滚动条时,组件只是更新现有itemRenderer的数据和位置,这一点,和以往Flash中的List组件是截然不同的。

比如,TileList、List组件, 如果数据源只有一条数据,显示区域可以同时显示十条, 则开始时只创建一个itemRenderer。当添加一条数据,则创建一个新的itemRenderer。当数据量超过显示区域的最大值10时,就不再创建新的itemRenderer,拖动滚动条,itemRenderer数据被自动更新。我们所看到的滚动条是一个假象,仅仅用来作标示所用。

另外,TileList、List最先会创建一个隐藏的itemRenderer。由于itemRenderer的不确定性,主控件无法确定元素的尺寸,因此,程序将自动创建一个名为“hiddenltem”的itemRenderer实例,计算大小。
附加:
关于dataProvider、itemRenderer、data的具体用法有些抽象,因此我特此列举一个例子来说明一下。
这是一个HorizontalList组件,而且其中它的itemRenderer=ToolBoxRenderer,想让我们看一下HorizontalList的片段代码:
<mx:HorizontalList id="myHorizontalList" itemRenderer="ToolBoxRenderer">
         <mx:dataProvider>
             <mx:Array>
                   <mx:Object tooltip= "rubber" styleName="rubber" language="{ _language }"/>
             </mx:Array>
         </mx:dataProvider>
</mx:HorizontalList> 

然后是ToolBoxRenderer的片段代码:

<mx:Canvas width="30" height="30">
         <mx:Button
            width="30" height="30" 
            toolTip="{ data.tooltip }" 
            styleName="{ data.styleName }"/>
</mx:Canvas>

再让我们看看itemRenderer是如何与我们今天这个主题联系起来的。
1、在myHorizontalList中定义了一个dataProvider,通过代码可以看出是一个Array类型的变量,然后将其赋值给dataProvider。这个时候,其实就应该将数据显示到myHorizontalList上面了,这也就是dataProvider的用处。
2、在dataProvider包含的Array中,定义如下的结构:<mx:Object tooltip= "rubber" styleName="rubber" language="{ _language }"/>
3、我们不仅设定了dataProvider,还是同时设定了itemRenderer,即为ToolBoxRenderer。
4、在ToolBoxRenderer里面,定义了一个Button,同时我们使用类似于这样的方式可以取得dataProvider里面的数据:toolTip="{ data.tooltip }" 


   

Flex3.0实战之itemRenderer

   

Flex中提供了大量用于数据呈现的组件,这其中,以List系列组件最为常见,使用也最频繁,比如ComBoBoxListTreeTileListDataGrid等等。这些组件有一个共同的特性,那就是支持自定义itemRenderer,这个功能非常强大,能够帮助我们实现很多实用的功能,本文将介绍itemRenderer的相关知识和具体应用。

什么是itemRenderer?

itemRenderer,可以理解为数据的表现方式,具体地说,是指显示每一条数据时采用的形式。在使用数据处理类组件时,我们只需要把数据按照一定的格式组织好,然后赋予给组件,剩下的事就不用费心了。

每一个组件都有默认的itemRenderer,比如List组件:

List组件默认的itemRenderer类似Label组件,只简单显示一行文本。如右图所示,红色方框选中的是一个itemRenderer

本质上,itemRenderer和其它容器类组件没有区别,里面可以包括任意的可视化元素,包括文本、图片、视频等,只要是Flex支持的视觉元素,都可以。

自定义itemRenderer

组件默认的itemRenderer都过于简单,如果想加强表现力,就必须创建个性化的itemRenderer

自定义itemRenderer有两种方式:一种是嵌入式,直接写在组件的标签中,所有的代码都集中在一个MXML文件中;另一种是把itemRenderer独立出来,形成一个MXML组件或ActionScript类。

下面我们还是以List组件为例,这里为了方便测试,重新定义了数据结构。每条数据都是一个XML节点,包含了下面的这些信息:

然后创建一个新的MXML组件ProductltemRenderer.mxml,扩展了Canvas容器,内容如下:

请注意看上面的代码:两个组件Image和Label的关键属性都和data对象的属性值绑定起来。“data”对象从何而来?它正是itemRenderer能够和组件保持独立的关键点,是List组件和itemRenderer进行数据交换的途径。
Canvas容器和其它所有的容器类组件一样,都定义了名为“data”的存取器,是个object类型,也就是setter和getter函数:
组件通过这个接口将数据传给itemRenderer,从而实现了数据表现形式和逻辑处理的分离。同时,data存取器添加了数据绑定的支持,可以直接拿来操作。为了适应所有的数据类型,getter的返回类型被设为Object,保证数据的统一。
比如这里,通过data可以获取三个属性:title、version和logo。

下面就在程序中使用这个新创建的itemRenderer

整个过程非常简单,只需要修改组件的itemRenderer属性即可。注意,这里的属性值是ActionScript类的完整路径(MXML组件也相当于ActionScript)

如果换作嵌入式方式,上面的代码可以修改为:

MXML代码中的mxComponent标签不可缺少,否则,编译器无法识别嵌入的组件

一般情况下,不建议使用这种方式,这使得单一文件的结构复杂,降低了代码的可读性。为了方便扩展和维护,提高代码的重用性,我们应该使用第二种方式。



本例覆盖了 set data() 函数以检查数据并设置 itemRenderer 的 backgroundColor。这十分常见。覆盖 set data() 使您能截取为新行更改数据的时间, 并且您可以作出样式更改。

    常见错误为:

    忘记调用 super.data = value;。这是致命错误-它会把 itemRenderer 弄乱。

    忘记重置样式 (如果任何测试失败)。当 pubDate 是将来时, 可能只设置颜色会比较诱人, 但您必须记住, itemRenderer 是循环使用的, 所以 else 语句很有必要。



 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值