这两个容器可容纳任何继承自DisplayObject并实现IVisualElement接口的子项,但主要用于容纳数据项子项,数据项可以是简单的字符串,数字等对象,也可以是复杂的对象,如Object和XMLNode 。
两个容器的主要区别:
- SkinnableDataContainer可以使用皮肤,DataGroup则不能,但性能更好。
- DataGroup通过作为Scroller的子项来实现滚动条支持, SkinnableDataContainer则在皮肤中实现。
- DataGroup的默认布局为BasicLayout,SkinnableDataContainer的默认布局为VerticalLayout。
通过将实现了
IList接口的集合对象赋值给容器的
dataProvider属性来向容器提供要显示的数据。
数据集可以混合不同类型的数据项,或者混合数据项和Flex组件,在
itemRendererFunction中选择不同项对应的
item renderer。
item renderer定义了数据项在容器中的可视表示,可以使用默认提供的两种呈现器:
- spark.skins.spark.DefaultItemRenderer:将数据转换为字符串,使用Spark Label控件显示。
- spark.skins.spark.DefaultComplexItemRenderer:显示一个包含在Group容器中的Flex组件,常用于容器子项为可视组件的情况,如果不想组件被包含在Group容器中,将itemRenderer设置为null。
注意:如果所有子项都是可视组件,应该使用
Group
或
SkinnableContainer
作为容器。
通过
dataProvider的
addItem()和removeItemAt()方法可以在运行时删除或添加项。
使用virtualization
自定义item renderer
可以使用MXML和AS来定义,前者容易编写,后者性能更好。如使用as定义,在移动应用中,继承spark.components.LabelItemRenderer,桌面应用中继承mx.core.UIComponent。
item renderer通常实现以下两个接口:IDataRenderer(定义数据属性,必须实现),IItemRenderer(定义与主机组件间通信的API用于支持用户交互)。
主机组件必须实现IItemRendererOwner接口以传递数据给item renderer。
item renderer可以定义视图状态,所有的视图状态都是可选的。
id为labelDisplay的Label组件比较特殊,会默认用来显示字符串数据,并且主机组件将使用该组件来确定baselinePosition的值。
移动和桌面应用中item renderer的区别
- 移动应用中item renderer的尺寸一般比桌面应用中的大。
- 两者表示项被选中的方式不一样。
- caret的表示不一样。
- 一般桌面应用中使用MXML创建,移动应用中使用AS创建,如果主机组件只包含很少的数据项或不支持滚动,也可以使用MXML来创建。
移动和桌面应用中item renderer的交互
传递数据到Spark item renderer中
- 通过IDataRenderer和IItemRenderer接口。
- hovered属性。
- 使用UIComponent的owner属性访问主机组件。
- 通过IItemRendererOwner接口。
- 可以选择在主机组件或item renderer中处理数据项。
- 覆盖IItemRenderer.label。
- 覆盖IItemRendererOwner.itemToLabel()方法。
- 数据绑定或覆盖IIDataRenderer.data属性。
- 使用dataChange事件。
使用
itemRendererFunction方法
function itemRendererFunction(item:Object):ClassFactory
可以为不同的数据项指定不同的
item renderer,返回null则不使用
item renderer。
private function selectRenderer(item:Object):ClassFactory { var classFactory:ClassFactory; if (item is String) { // If the item is a String, use DefaultItemRenderer. classFactory = new ClassFactory(DefaultItemRenderer); } else { // If the item is an Object, use MySimpleItemRendererFunction. classFactory = new ClassFactory(MySimpleItemRendererFunction); } return classFactory; }
优先级
- 优先使用itemRendererFunction,没有或返回null,则使用规则2.
- 使用itemRenderer。
- 项实现mx.core.IVisualElement,并且是flash.display.DisplayObject的子类,直接显示。
- 以上都不满足,则运行时错误。
为虚拟布局创建可循环使用的item renderer
当虚拟布局启用时,容器只为可见的项创建item renderer,当一个子项被移出容器的可见范围时,它的item renderer会被循环使用,data属性将被新子项的数据设置,如果有依赖data属性的行为,必须验证data是否为null。
item render被重新赋值时,Flex会调用
updateRenderer()方法,来设置owner和label属性。如果是
SkinnableDataContainer的子类,会设置更多额外的属性。
要注意保证组件的状态会被正确的重置,不能依赖组件的默认状态,因为被重新复制时组件可能已经不处在默认状态了。
定义典型项来决定item renderer的尺寸
可以通过设置typicalItem属性或
typicalLayoutElement属性来决定每一项的默认大小。
使用MXML创建item renderer
可以通过设置ItemRenderer.autoDrawBackground属性来决定是否使用默认背景。
可以覆盖itemIndex属性来执行与项索引有关的操作。
定义item renderer的视图状态
主机组件为 spark.components.supportClasses.ListBase的子类的类实现了更多的视图状态, DataGroup和SkinnableDataContainer实现了部分视图状态。
定义item renderer的视图状态
主机组件为 spark.components.supportClasses.ListBase的子类的类实现了更多的视图状态, DataGroup和SkinnableDataContainer实现了部分视图状态。
可以添加自定义的视图状态。
可以使用
<fx:Component>来定义内联的item renderer,
这将创建一个新的作用域,需要访问外部作用域,使用
outerDocument关键字。也可以不内联而定义在
<fx:Declarations>中,
通过
<fx:Component>的
className属性来赋值到主机组件的
itemRenderer属性
,
以便在当前文档内重用。
使用AS创建item renderer
有以下方法用于创建AS item render:
- 创建现有item renderer的子类,比如spark.components.LabelItemRenderer,spark.components.IconItemRenderer,或者spark.components.supportClasses.ItemRenderer。使用spark.components.LabelItemRenderer可以获得最高的性能。在子类中可以控制背景显示和数据项的布局。如果想使用Flex的内建布局机制,且不是很在意性能,就创建spark.components.supportClasses.ItemRenderer的子类。
- 创建mx.core.UIComponent的子类。可以获得最好的性能,需要实现mx.core.IDataRenderer和spark.components.IItemRenderer接口。
实现一个item renderer需要覆盖必要的方法,和调用必要的
invalidation方法,具体取决于继承的父类。