您的位置:首页 > 其它

自定义Spark item的渲染器(Define a custom Spark item renderer)

2011-04-19 11:27 267 查看

自定义
Spark item
的渲染器(
Define
a custom Spark item renderer



DAtaGroup

SkinnableDataContainer
或它们的子类中定义自己的项目渲染器可以控制数据项的显示外观,数据项的外观包括字体、背景色、边界和其他的可视方面。

项目渲染器也可以在和用户进行交互的时候指定要显示的外观。例如,用户鼠标移动到数据项上时显示一种外观,当用户点击时显示另一种外观。

Spark
项目渲染器的基类
ItemRenderer
已经内置支持了所有用户要进行交互。缺省项目渲染器
DefaultItemRenderer

DefaultComplexItemRenderer
支持这些用户的交互操作。

在你自定义的项目渲染器中,你可以选择依赖
ItemRenderer
类支持的缺省交互支持还是实现你自己的交互。

许多
Spark
组件既支持皮肤也支持项目渲染器。当项目渲染器定义了数据项的外观,皮肤定义了组件完整的可视化外观。皮肤可以包含边界、滚动条和组件外观的其他方面。详细的信息参考
Spark
Skinning



item
渲染器的架构

为了更好的理解项目渲染器是如何工作的和查阅自定义项目渲染器是如何实现的,请看下面的代码。下面的代码演示了给
SkinnableDataContainer
容器自定义的项目渲染器,这段代码的作用是当鼠标移动到控件上时,数据项的字体颜色改变。

<?xml version="1.0"
encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleCustomItemRenderer.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:states>

<s:State name="normal"/>

<s:State name="hovered"/>

</s:states>

<s:Label id="labelDisplay"

verticalCenter="0"

left="3" right="3" top="6" bottom="4"

fontSize.hovered='14' fontStyle.hovered="italic"/>

</s:ItemRenderer>

所有项目渲染器的基类是
ItemRenderer
类,此类是
Group
类的子类,所以它本身也是一个容器。在
ItemRenderer
类的内部定义了布局、状态和用于显示数据项的子控件。

ItemRenderer
类的缺省布局是
BasicLayout
。在这个实例中,由于没有指定
Layout
属性,本项目渲染器仍然使用
BasicLayout


徐昂木渲染器也可以定义视图的状态。所有的视图状态都是可选的。在本实例中,你可以处理
normal

hovered
视图状态。
normal
状态定义了数据项在没有和用户进行交互时显示的外观,而
hovered
状态定义了鼠标移动到数据项时的外观。

本实例使用
hovered
视图状态来更改用户将鼠标移动到数据项时的字体,字体被更改为
14 point
、斜体。关于在项目渲染器中使用视图的状态更多的信息请参考


Spark容器定义项目渲染器的视图状态



Label
控件被居中垂直显示在项目渲染器的显示区域,它距离左边界的距离限制为
3
个像素,距离上边界
6
个像素,距离底边界
4
个像素。你可以在自己的项目中通过模仿上面的代码,在你自己的项目渲染器中使用这些设置,或者在必要的时候更改这些设置。

在项目渲染器中
Label
控件的
id

labelDisplay
。在一个项目渲染器中这是一个指定命名的组件。
Flex
写表示数据的字符串将会写入到
labelDisplay
组件中。
Flex
也使用
labelDisplay
组件来决定在宿主组件中
baselinePosition
数据的值。

下面的应用使用了这个自定义项目渲染器:

<?xml version="1.0"
encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerSimpleIR.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer

itemRenderer="myComponents.MySimpleCustomItemRenderer">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:String>Bill Smith</fx:String>

<fx:String>Dave Jones</fx:String>

<fx:String>Mary Davis</fx:String>

<fx:String>Debbie Cooper</fx:String>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

在一个项目渲染器中控制一个数据项目的背景色

ItemRenderer
类定义了所有用户交互时的缺省背景颜色,当没有用户交互时项目渲染器缺省画一个透明的背景色。当用户碰到它时会画一个浅蓝色的背景。

有些子类,例如:
DataGroup

SkinnableDataContainer
的子类
List
支持更多的用户交互。例如:
List
控件支持数据项的选择。当用户选择了一个数据项,项目渲染器缺省画一个深蓝色的背景色。

当用户定义定义了自己的项目渲染器时,你可以选择使用缺省的背景色还是定义自己的。如果使用缺省的,你的项目渲染器将显示和缺省项目渲染器相同的外观。

ItemRenderer
类使用
CSS
样式来定义不同的视图状态。你可以通过更改
contentBackgroudColor

selectionColor
的值来制定渲染器的缺省颜色。例如:

l

contentBackgroundColor =
0xFFFFFF (white)

l

rollOverColor = 0xCEDBEF

l

selectionColor = 0xA8C6EE

这些颜色定义在
spark..swc

default.css
文件中如果你想要自己的项目渲染器模仿
Flex
的设置,在自己的项目渲染器中使用相同的设置。

下面的示例展示了如何设置
rollOverColor
样式为绿色:

<?xml version="1.0"
encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerSimpleIRStyled.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Style>

@namespace s "library://ns.adobe.com/flex/spark";

s|ItemRenderer { rollOverColor : green }

</fx:Style>

<s:SkinnableDataContainer

itemRenderer="myComponents.MySimpleCustomItemRenderer">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:String>Bill Smith</fx:String>

<fx:String>Dave Jones</fx:String>

<fx:String>Mary Davis</fx:String>

<fx:String>Debbie Cooper</fx:String>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

如果要完全控制项目渲染器的背景色,需要将
ItemRenderer.autoDrawBackground
属性设置为
false
。此属性设置为
false
后,你自己的项目渲染器负责显示所有用户交互的背景色。

下面代码展示了将
SkinnableDataContainer
容器中的项目交替显示白色和绿色的背景色。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MyAlternatingItemRenderer.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

autoDrawBackground="false">

<fx:Script>

<![CDATA[

// Make the default background
color white.

[Bindable]

public var myBGColor:int =
0xFFFFFF;

// Override the itemIndex set
function to draw a

// white background behind even
number items,

// and a green background behind odd
numbered items.

override public function set
itemIndex(value:int):void {

if ((value%2) == 0) {

myBGColor= 0xFFFFFF;

}

if ((value%2) == 1) {

myBGColor= 0xCCFF66;

}

}

]]>

</fx:Script>

<s:states>

<s:State
name="normal"/>

<s:State
name="hovered"/>

</s:states>

<s:Rect id="myRect"

left="0" right="0"
top="0" bottom="0"

alpha="1.0">

<s:stroke>

<s:SolidColorStroke

color="0xA8C6EE"

weight="1"/>

</s:stroke>

<s:fill>

<!-- Bind the myBGColor property
to the fill color. -->

<s:SolidColor

color="{myBGColor}"/>

</s:fill>

</s:Rect>

<s:Label id="labelDisplay"

verticalCenter="0"

left="3" right="3"
top="6" bottom="4"

fontSize.hovered='14'
fontStyle.hovered="italic"/>

</s:ItemRenderer>

这个示例重写了
ItemRenderer
类的
itemIndex
属性。
itemIndex
属性包含有数据项在宿主组件的数据提供者中的索引值,重写它会设置奇数行背景色为绿色,偶数行背景色为白色。

下面的代码展示了如何引用上面的项目渲染器:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerAlternatingIR.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer

itemRenderer="myComponents.MyAlternatingItemRenderer">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:String>Bill
Smith</fx:String>

<fx:String>Dave
Jones</fx:String>

<fx:String>Mary
Davis</fx:String>

<fx:String>Debbie
Cooper</fx:String>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

将参数传递给
Spark
项目渲染器中

项目渲染器的宿主组件称之为项目渲染器的拥有者。项目渲染器的基类
ItemRenderer
定义了几个属性,宿主组件可以通过它们将一些信息传递给当前渲染器。

u

label

表示数据项的字符串。原始的数据项要么是一个字符串要么是项目渲染器的拥有者将数据项转换为一个字符串。

u

data

原始的数据项

u

owner

项目渲染器的宿主,例如:如果
SkinnableDataContainer
是一个项目渲染器的拥有者,那么可以通过
ItemRenderer.owner
属性来访问它。

u

dragging

如果该渲染器可以拖拽则值为
true


u

itemIndex

在宿主组件的数据提供者中的索引值。

u

selected

如果项目渲染器本身可以显示为选中则值为
true
。例如
Spark List
控件可以进行选中,但是
DataGroup
容器就不能被选择。

u

showCaret

如果项目渲染器本身可以被设置焦点则值为
true


项目渲染器的宿主必须实现
IItemRendererOwner
接口。此接口定义了下面这些方法,以便项目渲染器可以将必要的信息写入里面。

itemToLabel()
——将数据项转换为字符串表达式。组件可以重写此方法来定义自己的字符串转换。

updateRenderer()
——将数据项作为字符串写入到
ItemRenderer.label
属性中。更新
ItemRenderer.owner
属性中的宿主组件。此方法的最后一件事是设置项目渲染器的数据属性。组件可以重写此方法以便将一些额外的信息传递给项目渲染器。

在你建立自定义的项目渲染器之前,需要决定如何将数据项传递给项目渲染器。在某些情况中,你在传递数据给项目渲染器之前需要进行一些数据项的处理。如果是这样,需要在宿主组件中重写
itemToLabel()

updateRenderer()
方法。项目渲染器之后就可以通过
label
属性来访问数据了。

如果不是宿主组件处理数据项而是项目渲染器来执行处理。使用
ItemRenderer.data
属性传递数据项。项目渲染器之后可以访问
data
属性并在显示数据之前执行必要的处理。

重写
itemToLabel()

updateRenderer()
的示例参考
使用

ItemRenderer.label属性传递参数

。使用
data
属性的示例参考
使用

ItemRenderer.data属性传递数据




使用
ItemRenderer.lable
属性传递数据

如果数据项是一个字符串或者值,它可以很容易的转换为字符串。你可以使用ItemRenderer.label
属性传递给项目渲染器。如果数据项必须转换为字符表达式,可以重写宿主组件中的itemToLabel()
方法来定义自己的转换。

下面示例中,SkinnableDataContainer
容器中的子元素根据字符串定义不同的颜色。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataContainerColor.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:MyComps="myComponents.*">

<s:SkinnableDataContainer

itemRenderer="myComponents.MySimpleColorRenderer">

<mx:ArrayList>

<fx:String>red</fx:String>

<fx:String>green</fx:String>

<fx:String>blue</fx:String>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

这个示例使用了叫
MySimpleColorRenderer
的自定义项目渲染器。该渲染器定义在
MySimpleColorRenderer.mxml
文件中,它的作用是根据文本字符串显示相应的背景色。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleColorRenderer.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

autoDrawBackground="false">

<fx:Script>

<![CDATA[

// Property to hold the RGB color
value.

[Bindable]

public var myColor:uint;

// Write String to labelDisplay
component.

override public function set
label(value:String):void

{

super.label = value;

labelDisplay.text = label;

// Determine the RGB color
value from the data item.

if (label == "red")

myColor = 0xFF0000;

if (label == "green")

myColor = 0x00FF00;

if (label == "blue")

myColor = 0x0000FF;

}

]]>

</fx:Script>

<!-- Set the background color to the RGB
color value.-->

<s:Rect width="100%"
height="100%" alpha="0.5">

<s:fill>

<s:SolidColor
color="{myColor}" />

</s:fill>

</s:Rect>

<!-- Display the color name -->

<s:Label
id="labelDisplay"/>

</s:ItemRenderer>

在这个示例中,项目渲染器重新赋值了
label
属性,将颜色值写入
Label
控件中,并填充
Rect
组件的颜色。

项目渲染器显示数据并不是基于状态的改变。因此,需要设置
ItemRenderer.autoDrawBackground
的属性为
false
。这个项目渲染器用于显示没有其他用户交互功能的数据。如果要显示基于用户交互而显示更改的示例参见:
为配合

Spark容器给项目渲染器定义状态



如果要修改传递给
label
属性的字符串,需要重写宿主组件中的
itemToLabel()
方法。该方法的格式如下:

itemToLabel(item:Object):String

该方法有一个参数表示数据项。它返回要显示在数据渲染器中的字符串。

下面示例中每一个数据项由三个部分组成。自定义的
MyDAtaGroup
组件重写了
itemToLabel()
方法,该方法将对象进行格式化然后传递字符串给项目渲染器。这个示例使用了
DefaultItemRenderer
来显示文本。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerOverride.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:MyComps="myComponents.*">

<!-- Define a custom DataGroup container
to override the itemToLabel() method. -->

<MyComps:MyDataGroup
itemRenderer="spark.skins.spark.DefaultItemRenderer">

<MyComps:layout>

<s:VerticalLayout/>

</MyComps:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith" companyID="11233"/>

<fx:Object
firstName="Dave" lastName="Jones"
companyID="13455"/>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper"
companyID="14266"/>

</mx:ArrayList>

</MyComps:MyDataGroup>

</s:Application>

MyDataGroup.mxml
文件自定义了
SkinnableDataContainer
容器,它重写了
itemToLabel
()方法。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MyDataGroup.mxml -->

<s:SkinnableDataContainer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:s="library://ns.adobe.com/flex/spark"

xmlns:mx="library://ns.adobe.com/flex/mx">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<fx:Script>

<![CDATA[

// Override to return the Object as
a formatted String.

override public function
itemToLabel(item:Object):String {

var tempString:String;

if (item == null)

return " ";

tempString = item.firstName +
" " + item.lastName

+ " " + ",
ID: " + item.companyID;

return tempString;

}

]]>

</fx:Script>

</s:SkinnableDataContainer>


使用
ItemRenderer.data
属性传递数据

有时不需要在宿主组件中处理数据而是在项目渲染器自己来处理所有的数据项的显示,在这种情况下,
ItemRenderer.data
属性用于将数据传递给项目渲染器。有了这个技术,你就可以定义一组项目渲染器用来以不同的方式显示相同的数据。

下一个示例中,每一个数据项由一个对象来表示,它包含了三个部分:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerSimple.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer

itemRenderer="myComponents.MySimpleItemRenderer">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object firstName="Bill"
lastName="Smith" companyID="11233"/>

<fx:Object
firstName="Dave" lastName="Jones"
companyID="13455"/>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper" companyID="14266"/>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

SkinnableDataContainer
使用自定义的项目渲染器
MySimpleColorRenderer
。该渲染器将
firstName

lastName
显示在一个单独的
label
组件,将
companyID
显示在另一个
label
组件中:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRenderer.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:HGroup verticalCenter="0"
left="2" right="2" top="2"
bottom="2">

<s:Label text="{data.lastName},
{data.firstName}"/>

<s:Label
text="{data.companyID}"/>

</s:HGroup>

</s:ItemRenderer>

data
属性包含了传递给
DataGroup
组件的对象,该对象以原始的状态表示数据项。渲染器使用数据绑定来将控件和数据进行关联。两个
Label
组件定义在和
Group
容器中以便它们可以水平显示。

如果使用数据绑定,亦可以在项目渲染器中重写数据属性,使用重写你可以修改
data
或执行其他处理,这些是在
set
属性中完成。下面的示例展示了如何重写
data
属性。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRendererDataOverride.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Script>

<![CDATA[

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

super.data = value;

// Check to see if the data
property is null.

if (value== null)

return;

// If the data property is not
null,

// set the Label controls
appropriately.

nameLabel.text =
value.firstName + ', ' + value.lastName;

compLabel.text =
value.companyID;

}

]]>

</fx:Script>

<s:HGroup verticalCenter="0"
left="2" right="2" top="2"
bottom="2">

<s:Label
id="nameLabel"/>

<s:Label
id="compLabel"/>

</s:HGroup>

</s:ItemRenderer>


为配合
Spark
容器给项目渲染器定义状态

项目渲染器支持任意的视图状态。
Flex
定义一些默认的状态如下所示:

n

normal

不需要用户交互的数据状态

n

hovered

当鼠标悬停在数据项时
.

n

selected

当该数据项被选中时

n

dragging

当该数据项被拖拽时

n

normalAndShowCaret

数据项时
normal
状态,且在项目列表中处于焦点状态

n

hoveredAndShowCaret

数据项处于悬停状态,且在项目列表中处于焦点状态

n

selectedAndShowCaret

该数据项处于
normal
状态,且在项目列表中处于焦点状态

当用户和控件进行交互时,更改了项目渲染器的视图状态,
Flex
首先要确定该项目渲染器是否定义了该视图状态。如果定义了,
Flex
设置项目渲染器使用该状态。如果没有定义,则忽略。

selected,
normalAndShowCaret, hoveredAndShowCaret, and selectedAndShowCaret
这些视图状态由基于
list
的组件支持。基于
list
的组件是
spark.components.supportClasses.ListBase
的子类。
DataGroup

SkinnableDataContainer
容器并没有实现这些视图状态。

DefaultItemRenderer

DefaultComplexItemRenderer
容器支持所有的视图状态。所以你可以在基于
list
的组件中使用这些渲染器。

你的项目渲染器支持的视图状态根据每种视图状态的改变执行相应的动作。例如,你可以根据视图状态的更改来变化显示的内容或不变化。你也可以定义额外的视图状态。

下面的示例,你可以了
SkinnableDataContainer
容器来显示一个有四个属性的对象:
lastName

firstName

companyID

phone


<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerSimpleStates.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer
itemRenderer="myComponents.MySimpleItemRendererWithStates">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object firstName="Bill"
lastName="Smith"

companyID="11233"
phone="617-555-1212"/>

<fx:Object
firstName="Dave" lastName="Jones"

companyID="13455"
phone="617-555-1213"/>

<fx:Object
firstName="Mary" lastName="Davis"

companyID="11543"
phone="617-555-1214"/>

<fx:Object
firstName="Debbie" lastName="Cooper"

companyID="14266"
phone="617-555-1215"/>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

下面这个项目渲染器显示了在悬停状态的文本为粗体、蓝色字体:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRendererWithStates.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

autoDrawBackground="false">

<s:states>

<s:State
name="normal"/>

<s:State
name="hovered"/>

</s:states>

<s:HGroup verticalCenter="0"
horizontalCenter="0">

<s:Label text="{data.lastName},
{data.firstName}"

color.hovered="blue"

fontWeight.hovered="bold"/>

<s:Label
text="{data.companyID}"

color.hovered="blue"

fontWeight.hovered="bold"/>

<s:Label
text="{data.phone}"

color.hovered="blue"

fontWeight.hovered="bold"/>

</s:HGroup>

</s:ItemRenderer>

因为
SkinnableDataContainer
容器不支持
selected
视图状态,项目渲染器没有设定
selected
状态的任何定义。

也可以在项目渲染器中包含一个变幻。一旦你改变了视图状态,开始演示该变幻。下面的项目渲染器使用一个变幻来演示鼠标飞过该项目时的
companyID

telephone


<?xml version="1.0"
encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRendererWithTrans.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

autoDrawBackground="false">

<s:states>

<s:State
name="normal"/>

<s:State
name="hovered"/>

</s:states>

<s:transitions>

<s:Transition
fromState="normal">

<s:Sequence>

<s:Resize target="{this}"
/>

<mx:SetPropertyAction
targets="{[cID, empPhone]}"

name="visible"
value="true" />

</s:Sequence>

</s:Transition>

<s:Transition
toState="normal">

<s:Sequence>

<mx:SetPropertyAction
targets="{[cID, empPhone]}"

name="visible"
value="false" />

<s:Resize
target="{this}" />

</s:Sequence>

</s:Transition>

</s:transitions>

<s:VGroup verticalCenter="0"
horizontalCenter="0">

<s:Label text="{data.lastName},
{data.firstName}"

color.hovered="blue"

fontWeight.hovered="bold"/>

<s:Label id="cID"

includeIn="hovered"

includeInLayout.hovered="true"

includeInLayout.normal="false"

text="{data.companyID}"/>

<s:Label id="empPhone"

includeIn="hovered"

includeInLayout.hovered="true"

includeInLayout.normal="false"

text="{data.phone}"/>

</s:VGroup>

</s:ItemRenderer>

下面的示例使用了上面的项目渲染器:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerSimpleStatesTransition.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer
itemRenderer="myComponents.MySimpleItemRendererWithTrans">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"

companyID="11233"
phone="617-555-1212"/>

<fx:Object
firstName="Dave" lastName="Jones"

companyID="13455"
phone="617-555-1213"/>

<fx:Object firstName="Mary"
lastName="Davis"

companyID="11543"
phone="617-555-1214"/>

<fx:Object
firstName="Debbie" lastName="Cooper"

companyID="14266"
phone="617-555-1215"/>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

关于更多的视图状态参阅视图
状态

,更多的关于变幻的内容参阅
变幻




Spark
容器一起使用项目渲染器的函数

在某些应用中,在一个容器中显示数据项有不同的类型。或者在某些场景中,数据项的每一种类型需要有自己相应的项目渲染器。或者你需要将数据项和
Flex
组件混合在一个容器中。为实现这些功能,给数据项和
Flex
组件定义不同的项目渲染器。

你可以使用项目渲染器函数来测试每个数据项来决定使用哪一个渲染器。
DataGroup.itemRendererFunction

skinnableDataContainer.itemRendererFunction
方法使用下面的格式:

function itemRendererFunction(item:Object):ClassFactory

item
表示为一个数据项,返回的值是项目渲染器。如果
item

Flex
组件的子类,返回
DefaultComplexItemRenderer
来显示组容器中的子类。也可以返回
null
,表示不需要渲染器来显示子类。

下面的示例定义了项目渲染器方法:当参数为一个对象返回了一个项目渲染器,参数为字符串则返回另一个渲染器。

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerFunction.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Script>

<![CDATA[

import
myComponents.MySimpleItemRendererFunction;

import
spark.skins.spark.DefaultItemRenderer;

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;

}

]]>

</fx:Script>

<s:DataGroup
itemRendererFunction="selectRenderer">

<s:layout>

<s:TileLayout
requestedColumnCount="3"/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"
companyID="11233"/>

<fx:String>617-555-1212</fx:String>

<fx:String>Newton</fx:String>

<fx:Object
firstName="Dave" lastName="Jones"
companyID="13455"/>

<fx:String>617-555-5555</fx:String>

<fx:String>Newton</fx:String>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:String>617-555-6666</fx:String>

<fx:String>Newton</fx:String>

</mx:ArrayList>

</s:DataGroup>

</s:Application>

你也可以在数据项和
Flex
组件在一个容器内时使用项目渲染器方法。
Flex
组件实现
IVisulaElement
接口,因此不需要项目渲染器在屏幕上画它们。在你的项目渲染器方法中,你可以定义数据项是否需要相应
Flex
组件,如果要,项目渲染器方法返回
DefaultComplexItemRenderer
,代码如下:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerFunctionVisual.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Script>

<![CDATA[

import mx.core.IVisualElement;

import
myComponents.MySimpleItemRendererEmployee;

import
spark.skins.spark.DefaultComplexItemRenderer;

private function
selectRenderer(item:Object):ClassFactory {

var classFactory:ClassFactory;

if(item is IVisualElement){

// If the item is a Flex
component, use DefaultComplexItemRenderer.

classFactory = new
ClassFactory(DefaultComplexItemRenderer);

}

else if (item is Object){

// If the item is an
Object, use MySimpleItemRendererFunction.

classFactory = new
ClassFactory(MySimpleItemRendererEmployee);

}

return classFactory;

}

]]>

</fx:Script>

<s:DataGroup
itemRendererFunction="selectRenderer">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"
companyID="11233"/>

<fx:Object
firstName="Dave" lastName="Jones" companyID="13455"/>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper"
companyID="14266"/>

<s:Button label="Add
Employee"/>

</mx:ArrayList>

</s:DataGroup>

</s:Application>

Spark
项目渲染器的处理顺序

DataGroup

SkinnableDataContainer
容器使用下面的规则来决定项目渲染器作为它的构成部件:

1.

如果
itemRendererFunction
属性被定义,调用此方法来获得项目渲染器。如果没有定义则使用规则
2.

2.

如果
itemRenderer
属性被定义,使用指定的项目渲染器来显示该项。

3.

如果项目实现了
mx.core.IVisualElement
且它是
flash.display.DisplayObject
类型,则直接使用它。

4.

如果没有发现项目渲染器则抛出实时错误。


Spark
容器定义内置的项目渲染器

上面所有的项目渲染器示例都定义在
MXML
文件中,这使得它具有高度的可重用性。可以容易的在多个容器中引用它。

你也可以在一个组件中定义一个内置的项目渲染器。使用内置定义可以使得所有的代码被封装在一个单独的文件中。可以,它会降低重用性。

下面的示例展示了如何和
SkinnableDataContainer
容器一起使用内置项目渲染器:

<?xml
version="1.0" encoding="utf-8"?>

<!-- containers/spark/SparkDataGroupContainerInline.mxml
-->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:SkinnableDataContainer>

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"
companyID="11233"/>

<fx:Object
firstName="Dave" lastName="Jones"
companyID="13455"/>

<fx:Object firstName="Mary"
lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper"
companyID="14266"/>

</mx:ArrayList>

<s:itemRenderer>

<fx:Component>

<s:ItemRenderer>

<s:Group
verticalCenter="0" left="2" right="2"
top="2" bottom="2">

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:Label
text="{data.lastName}, {data.firstName}"/>

<s:Label
text="{data.companyID}"/>

</s:Group>

</s:ItemRenderer>

</fx:Component>

</s:itemRenderer>

</s:SkinnableDataContainer>

</s:Application>

注意你定义的内置项目渲染器使用的是
DataGroup
容器的
itemRenderer
属性。
itemRenderer
属性内的第一个子标签总是
<fx:Component>
。在
<fx:Component>
内部的代码和MySimpleItemRenderer.mxml
文件中的内容一样。

在内置组件中可以使用的项目

内置项目渲染器只有一个规定。你不可以建立一个空的
<fx:Component></fx:Component>
标签对。例如,你可以将效果、样式和渲染逻辑一起定义在内置渲染器中。

你在内置项目渲染器中可以包含下列项目:

u

Binding tags

u

Effect tags

u

Metadata tags

u

Model tags

u

Scripts tags

u

Service tags

u

State tags

u

Style tags

u

XML tags

u

id attributes, except for the
top-most component

使用组件标签

<fx:Component>
标签在MXML
文件中定义了一个新的作用范围,项目渲染器本身的作用范围通过使用<fx:Component></fx:Component>
标签对来加以界定。如果要访问作用范围外部的元素需要在元素名前加一个outerDocument
的前缀。

例如:你在主应用范围内定义了一个变量叫localVar
。你在渲染器内部定义了一个相同名字的变量。从渲染器内部访问外部的localVar
使用outerDocument
前缀,请看下面的示例的展示:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerInlineScope.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Script>

<![CDATA[

// Variable in the Application
scope.

[Bindable]

public var
localVar:String="Application scope";

]]>

</fx:Script>

<s:SkinnableDataContainer>

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"
companyID="11233"/>

<fx:Object
firstName="Dave" lastName="Jones"
companyID="13455"/>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper" companyID="14266"/>

</mx:ArrayList>

<s:itemRenderer>

<fx:Component>

<s:ItemRenderer>

<fx:Script>

<![CDATA[

// Variable in the
Renderer scope.

[Bindable]

public var
localVar:String="Renderer scope";

]]>

</fx:Script>

<s:Group
verticalCenter="0" left="2" right="2"
top="2" bottom="2">

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:Label
text="{data.lastName}, {data.firstName}"/>

<s:Label
text="{data.companyID}"/>

<s:Label
text="{'Renderer localVar = ' + localVar}"/>

<s:Label
text="{'Application localVar = ' + outerDocument.localVar}"/>

</s:Group>

</s:ItemRenderer>

</fx:Component>

</s:itemRenderer>

</s:SkinnableDataContainer>

</s:Application>

建立可重用的内置项目渲染器

不是在组件的内部定义一个内置项目渲染器,你可以定义一个在整个项目中可重用的项目渲染器。

为了建立一个可重用的内置的项目渲染器,需要指定
<fx:Component>
的className
属性,通过给这个类命名,你定义了一个方法来引用这个项目渲染器和项目渲染器的子元素。

下面的示例展示了使用<fx:Component>
标签来定义内置项目渲染器,并在两个容器内进行引用:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerInlineReuse.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<fx:Declarations>

<fx:Component
id="inlineRenderer">

<s:ItemRenderer>

<s:Group
verticalCenter="0" horizontalCenter="0">

<s:layout>

<s:HorizontalLayout/>

</s:layout>

<s:Label
text="{data.lastName}, {data.firstName}"/>

<s:Label
text="{data.companyID}"/>

</s:Group>

</s:ItemRenderer>

</fx:Component>

</fx:Declarations>

<s:SkinnableDataContainer
itemRenderer="{inlineRenderer}">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"
companyID="11233"/>

<fx:Object firstName="Dave"
lastName="Jones" companyID="13455"/>

<fx:Object
firstName="Mary" lastName="Davis"
companyID="11543"/>

<fx:Object
firstName="Debbie" lastName="Cooper"
companyID="14266"/>

</mx:ArrayList>

</s:SkinnableDataContainer>

<s:SkinnableDataContainer
itemRenderer="{inlineRenderer}">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Jim" lastName="Sullivan" companyID="11233"/>

<fx:Object
firstName="Joan" lastName="Connors"
companyID="13455"/>

<fx:Object
firstName="Jack" lastName="Wilson"
companyID="11543"/>

<fx:Object
firstName="Jeff" lastName="Lodge"
companyID="14266"/>

</mx:ArrayList>

</s:SkinnableDataContainer>

</s:Application>

在这个示例中,通过数据绑定为
itemRenderer
的属性值,来指定两个容器的渲染器。

建立一个可循环使用的项目渲染器

当可视化布局关闭时,
DataGroup

SkinnableDataContainer
容器为每一个子元素建立一个实例。当可视化布局打开时,容器只为当前显示的可视化子元素只建立必要的项目渲染器。可视化布局大大减少了使用
DataGroup

SkinnableDataContainer
容器过高的需求。

打开可视化布局时,一个子元素移动到容器的可视范围之外,它的项目被重复利用。首先,这个项目渲染器的
data
属性被设置为空。当这个项目渲染器被重新利用,它的
data
属性被设置为表示新数据的数据项。因此,如果循环使用的项目渲染器执行任何基于数据
data
属性的操作,它必须首先检查它的属性是否为空。

当项目渲染器被重新分配,
Flex
首先调用项目渲染器拥有者的
updateRenderer
()方法。这个方法必须设置
owner

label
属性。
SkinnableDataContainer
的子类可以使用
updateRenderer
()方法来设置额外的属性。

因为容器会重新使用项目渲染器,确保你要完全定义它的状态。例如,你在一个项目渲染器中使用了
CheckBox
控件用来显示
true
或者
false
值,此值来自于当前
data
属性。通常会犯得一个错误是
CheckBox
控件总是在它的缺省状态
à

unchecked
,它只会检查
data
属性的
true
值。

可是,
CheckBox
是会被回收的并且它有记住先前的状态。因此,检查
data
属性
false
值,如果它是
checked
状态,显式
uncheck
控件,如下面的示例所示:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRendererCB.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark"

dataChange="setMgr();">

<fx:Script>

<![CDATA[

private function setMgr():void {

// Check to see if the data
property is null.

if (data == null)

return;

// If the data property is not
null,

// set the CheckBox control
appropriately..

if (data.manager ==
"yes") {

mgr.selected = true;

}

else {

mgr.selected = false;

}

}

]]>

</fx:Script>

<s:HGroup verticalCenter="0"
left="2" right="2" top="2"
bottom="2">

<s:Label text="{data.lastName},
{data.firstName}"/>

<s:Label
text="{data.companyID}"/>

<s:CheckBox id="mgr"/>

</s:HGroup>

</s:ItemRenderer>

使用
ItemRenderer

dataChange
事件来探测
data
属性的更改,此事件在
data
属性改变时抛出。同样,你也可以覆盖
data
属性来完成此功能。

覆盖
ItemRenderer.data
属性本身完成此功能的示例如下所示:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/myComponents/MySimpleItemRendererCBData.mxml -->

<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<fx:Script>

<![CDATA[

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

super.data = value;

// Check to see if the data
property is null.

if (value== null)

return;

// If the data property is not
null,

// set the CheckBox control
appropriately..

if (value.manager ==
"yes") {

mgr.selected = true;

}

else {

mgr.selected = false;

}

}

]]>

</fx:Script>

<s:HGroup verticalCenter="0"
left="2" right="2" top="2"
bottom="2">

<s:Label text="{data.lastName},
{data.firstName}"/>

<s:Label
text="{data.companyID}"/>

<s:CheckBox id="mgr"/>

</s:HGroup>

</s:ItemRenderer>

定义一个典型项来确定项目渲染器的大小

当和
DataGroup

SkinnableDataContainer
容器一起使用可视化布局,你能够传递给容器一个数据项,该数据项定义了一个典型的数据项。容器接着使用这个典型的数据项,将其和项目渲染器联系起来并决定子元素的缺省大小。通过定义典型数据项,容器在绘制屏幕时不需要确定每一个子元素的大小。

使用容器的
typicalItem
属性示例如下所示:

<?xml
version="1.0" encoding="utf-8"?>

<!--
containers/spark/SparkDataGroupContainerTypicalItem.mxml -->

<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"

xmlns:mx="library://ns.adobe.com/flex/mx"

xmlns:s="library://ns.adobe.com/flex/spark">

<s:layout>

<s:VerticalLayout/>

</s:layout>

<fx:Script>

<![CDATA[

[Bindable]

public var typicalObj:Object = {

firstName:"Long first
name",

lastName:"Even longer
last name",

companyID:"123456",

manager:"yes"

};

]]>

</fx:Script>

<s:Scroller>

<s:DataGroup
itemRenderer="myComponents.MySimpleItemRendererCB"

height="100"

typicalItem="{typicalObj}"
>

<s:layout>

<s:VerticalLayout
useVirtualLayout="true"/>

</s:layout>

<mx:ArrayList>

<fx:Object
firstName="Bill" lastName="Smith"

companyID="11233"
manager="yes"/>

<fx:Object
firstName="Dave" lastName="Jones"

companyID="13455"
manager="no"/>

<fx:Object
firstName="Mary" lastName="Davis"

companyID="11543"
manager="yes"/>

<fx:Object firstName="Debbie"
lastName="Cooper"

companyID="14266"
manager="no"/>

<fx:Object
firstName="Bob" lastName="Martins"

companyID="11233"
manager="yes"/>

<fx:Object firstName="Jack"
lastName="Jones"

companyID="13455"
manager="no"/>

<fx:Object
firstName="Sam" lastName="Johnson"

companyID="11543"
manager="yes"/>

<fx:Object
firstName="Tom" lastName="Fitz"

companyID="14266"
manager="no"/>

<fx:Object
firstName="Dave" lastName="Mead"

companyID="11233"
manager="yes"/>

<fx:Object
firstName="Dave" lastName="Jones"

companyID="13455"
manager="no"/>

<fx:Object
firstName="Mary" lastName="Davis"

companyID="11543"
manager="yes"/>

<fx:Object
firstName="Debbie" lastName="Cooper"

companyID="14266"
manager="no"/>

</mx:ArrayList>

</s:DataGroup>

</s:Scroller>

</s:Application>

在这个示例中,你定义了一个
typicalObj
对象。该对象表明了
firstName

lastName
的长度。然后传递给容器的
typicalItem
属性。容器使用这个数据项联系到项目渲染器,并确定了子元素的大小。

更多的关于
typeicalLayoutElement
属性的信息参阅
设置布局中的行高和列宽

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: