`
tianshibaijia
  • 浏览: 1128520 次
文章分类
社区版块
存档分类
最新评论

关于Spark皮肤

 
阅读更多

Flex 4 Spark皮肤

Flex 4 skinning 模型中,皮肤控制器包括布局一个组件的所有可视元素。 新的体系结构使开发人员能更好地控制其组件的皮肤,就像一些结构化的易用工具的工作方式。以前,MX 组件使用Helo主题作为它们的皮肤,其皮肤主要通过样式属性来进行指定。

Spark皮肤可以包含多个对象如图形元素、 文本、 图像和过场变化。 皮肤支持状态,以便组件的状态更改时,皮肤也变化。皮肤状态和过程转换很好的进行了整合,以便你可以对皮肤的一个或多个部件添加效果而无需添加太多的代码。

MXML 中,你通常写Spark皮肤类。 你可以用来绘制该图形的元素的 MXML 图形标记 (或 FXG 组件),并使用 MXML ActionScript设定子组件。

Flex 4 皮肤的基类是spark.components.supportClasses.Skin 。 默认Spark皮肤基于 SparkSkin 类,即Skin类的子类。

一般情况下,你应把皮肤类中的所有可视元素放入皮肤类中。 这有助于保持模型和视图之间必要的隔离,模型是指逻辑和声明性结构的应用程序 ;视图是指皮肤的应用程序。皮肤所使用的属性应该定义在组件中(例如:滑动条中拇指滑块的位置),以便他们可由多个皮肤共享。

大部件指定的皮肤使用 BasicLayout 布局方案。 此类型的布局使用约束条件,这意味着你指定的每个元素使用如 leftrighttop bottom 这些属性来定义和其他元素的距离。 你还可以使用绝对定位如 x y 坐标来指定每个元素在皮肤类中的位置。

在创建皮肤时你通常不继承现有皮肤类。 相反,通常从现有的皮肤类的源码来创建另一个皮肤类更为容易。 特别是如果你打算为组件的多个实例或多个组件使用同一个皮肤时,请使用此方法。要更改单个实例的组件的皮肤可以使用 MXML 图形语法或应用内置样式语法。

在创建Spark的皮肤时,你可以使用 MXML ActionScript FXG、 嵌入式图像或上述任意组合。 你在自定义皮肤中最好不要运行时加载资源,例如:图像。

使用皮肤

通常,对某个组件指定Spark皮肤通过 CSS MXML两种方式。 使用 CSS,通过 skinClass 样式属性指定皮肤类,如以下示例所示:

s|Button { 
skinClass: ClassReference("com.mycompany.skins.MyButtonSkin"); 
}

当使用 MXML 指定皮肤时,配置 skinClass 属性值来指定某个皮肤类名称,如以下示例所示:

<s:Button skinClass="com.mycompany.skins.MyButtonSkin" />

你还可以使用 ActionScript 语言指定的组件的皮肤。 在目标组件上调用 setStyle() 方法,并指定 skinClass 样式属性的值,如以下示例所示:

myButton.setStyle("skinClass", Class(MyButtonSkin));

skin类的解析

定义逻辑、 图形元素、 子组件、 状态,和其他对象来组成一个Spark组件的皮肤,自定义Spark皮肤是一个 MXML 文件。

Spark皮肤类的结构类似其他自定义的 MXML 组件。 他们包含以下元素:

· 皮肤根标记或一个皮肤的子类(必须的)

· 宿主组件元数据 (可选,但推荐使用)

· 状态声明 (如果定义了宿主组件则必须使用)

· 皮肤部件 (如果定义了宿主组件则必须使用)

· 脚本块 (可选)

· 图形元素和其他控件 (可选)

除了这些的元素,Spark皮肤可以包含 MXML 语言标记,例如:声明和所需的库等。

根标记(root tags

皮肤类使用皮肤类或一个皮肤类的子类,例如: SparkSkin,作为他们的根标记。 根标记包含皮肤类中所有使用到的命名空间声明。以下通常使用在每个皮肤类文件的顶部:

<s:Skin 
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:Skin> 标记内设置额外的属性,例如: minWidth scaleX 。 你也能设置样式属性,例如 color fontWeight。 此外,你可以在根标记中指定基于控件状态的值。 例如:color.down="0xFFFFFF"。 你不能在皮肤类的跟标签中设置 includeIn excludeFrom 属性。

如果你为应用程序创建自定义主题,或者如果你在你的自定义皮肤类中不需要支持全局Spark样式,你可以使用skin,而不是 SparkSkin 作为自定义皮肤的根标记。 SparkSkin 类对着色样式 (例如,chromeColor symbolColor)添加了支持,支持特定皮肤部件去除着色,支持指定符号的着色。

宿主组件

Spark皮肤类通常对其指定宿主组件。 宿主组件是使用皮肤的那个组件。 通过指定宿主组件,Spark皮肤可以使用宿主组件的属性,也可以获取该组件实例的引用。 下面的示例展示了Spark Button作为宿主组件:

<fx:Metadata> 
[HostComponent("spark.components.Button")] 
</fx:Metadata>

添加 [HostComponent] 元数据是可选的,但它可以使 Flex 执行编译时检查皮肤状态和所需的皮肤部件。 没有这种元数据就不能执行编译时检查。

皮肤状态

皮肤状态使皮肤元素关联到组件状态。 他们和组件状态不同。 例如:当按钮关闭时,按钮的皮肤显示与状态 down 状态相关联的元素。 当按钮弹起时,该按钮将显示 up 状态与相关联的元素。

自定义皮肤必须声明宿主组件里有的皮肤状态。 在运行时,该组件设置合适的状态。 皮肤状态使用点符号来指定,即 property.state (例如 alpha.down 定义 alpha 属性的值处于 down 状态)。

下面的示例显示了Spark按钮的皮肤状态:

<s:states> 
<s:State name="up" /> 
<s:State name="over" /> 
<s:State name="down" /> 
<s:State name="disabled" /> 
</s:states>

皮肤部件

皮肤部件是皮肤类和宿主组件中定义的组件。 他们经常提供一种方法使宿主组件能够传送数据给皮肤。 该组件也使用皮肤部件来捕获行为事件。

Spark容器皮肤包含一个内容组,它定义了子内容要放入的位置并在此展示。 此元素有一个 contentGroup 的标识。 所有 有皮肤的容器都有一个 contentGroup。 内容组是一个静态的皮肤部件。

布局

skin SparkSkin 类使用 BasicLayout 作为其默认布局方案。 这是相当于在皮肤类中这样定义:

<s:layout> 
<s:BasicLayout/> 
</s:layout>

当有多个图形元素或子组件在皮肤中使用时,布局方案就显得很重要了。 BasicLayout 依赖于限制和绝对定位来决定组件放置的位置。

子组件

Spark皮肤类通常包括图形元素和构成外观的皮肤的其他组件。

脚本块(可选)

Spark皮肤类可以包括确定皮肤逻辑的一个脚本块。

大多数Spark皮肤在顶部有一个 <fx:Script> 块。 此块通常定义皮肤类的样式属性,包括,皮肤使用的排除样式属性。 该标记包括一个特定的属性 fb:purpose="styling"

<fx:Script fb:purpose="styling">

此属性由 Flash 生成器使用。 当在 Flash 生成器中创建的该皮肤类副本时,你可以选择该皮肤是否可以有样式。如果有样式,Flash 生成器将包括皮肤类这一部分。 如果你选择无样式,Flash 生成器去除此部分。

语言标签

像任何基于 MXML 的类,你可以使用根标记内的库标记来声明重复的元素定义。 要使用在皮肤类中使用非可视对象,必须包含在声明标记中。

包括的皮肤类版本

虽然新的Spark skinning 体系结构使你创建自己的皮肤更加容易,Flex 4 还包含几个皮肤集合。

下表描述了 Flex 4 附带的 skinning 包:

软件包

说明

spark.skins.spark.*

Spark组件的默认皮肤。

spark.skins.wireframe.*

是一个开发应用的简化的主题,它使用"原型"开发。 要使用wireframe皮肤,你可以应用wireframe主题,或将该皮肤应用每个组件的基础上。

相关应用主题的信息,请参阅 使用主题

mx.skins.halo.*

MX 皮肤对 MX 组件有效,而和Spark组件皮肤结构并不一致的。 通过重写样式,加载helo主题样式,或通过设置 compatibility-version 3的编译器选项编译你的应用程序,可以使用helo皮肤而不是Spark皮肤中。

相关信息请看MX 组件皮肤

mx.skins.spark.*

当使用缺省Spark主题时,MX 组件使用的缺省皮肤。

这些皮肤在 Flex 4 应用程序中由 MX 组件使用。 这些皮肤在 Flex 4 应用程序中给 MX 组件类似Spark组件的皮肤。

mx.skins.wireframe.*

MX 组件的wireframe皮肤。

皮肤通常遵循这样的命名约定 componentName Skin.mxml。 在Adobe Flash 平台ActionScript 3.0 参考手册 中,大多数的皮肤都有几个版本。 例如,有四个名为 ButtonSkin 的类。 spark.skins.spark.* 包是Spark组件的默认皮肤。

flex 4 也附带了几个主题,它们使用某些 skinning 包。更多的信息,请参阅 关于主题文件

皮肤定义规则

在皮肤类和组件的之间的 skinning 规则定义了每个成员必须遵守的规则,以便于他们可以彼此进行通信。

皮肤类必须声明的皮肤状态,并定义皮肤部件的外观。 皮肤类通常还要指定该宿主组件,并设定在宿主组件中的数据。

组件类必须在元数据中标示皮肤状态和皮肤部件。 如果皮肤类要使用宿主组件上的数据,该宿主组件必须定义该数据。

下表显示了skinning规则:

皮肤类

宿主组件

宿主组件

<fx:Metadata> 
[HostComponent("spark.components.Button")] 
</fx:Metadata> 

n/a

皮肤状态

<s:states> 
<s:State name="up"/> 
</s:states>
[SkinState("up")]; 
public class Button { 
... 
}

皮肤部件

<s:Button id="upButton"/>
[SkinPart(required="false")] 
public var:upButton Button;

数据

text="{hostComponent.title}"
[Bindable] 
public var title:String;

编译器验证 [HostComponent][SkinPart][SkinState] 的元数据(只要 [HostComponent] 元数据在皮肤类中定义了)。 这意味着,皮肤状态和皮肤宿主组件标识的部件必须在皮肤类中声明。

宿主组件中的每个 [SkinPart] 元数据,编译器都要检查public变量或属性是否存在于皮肤类中。 宿主组件中的每个 [SkinState] 元数据,编译器都要检查皮肤类中是否存在这种状态。 有[HostComponent] 的元数据的皮肤,编译器尝试解析该宿主组件类,因此它必须完全是可以验证的。

一个组件和其皮肤类之间的规则有效,就可以对该组件使用该皮肤了。

访问宿主组件

Spark皮肤 可以指定宿主组件。 这不是对组件实例的引用,而是对组件类的引用。使用以下语法定义宿主组件:

<fx:Metadata> 
[HostComponent(component_class)] 
</fx:Metadata>

例如:

<fx:Metadata> 
[HostComponent("spark.components.Button")] 
</fx:Metadata>

如果皮肤定义此元数据,Flex 会对皮肤类创建该类型的属性-- hostComponent。然后,你可以在皮肤内使用此属性来访问宿主组件实例的成员。 例如在一个按钮的皮肤,你可以访问按钮的样式属性或其数据 (例如:label)。

通过对hostComponent 属性进行强类型转换为该组件的引用,你可以访问皮肤的宿主部件的公共属性。

<s:SolidColor color="{hostComponent.someColor as uint}" />

这只适用于直接在宿主组件声明的公共属性。 你不能使用此访问宿主组件的私有或受保护属性。

若要访问皮肤内宿主组件的样式属性的值,就无需要指定宿主组件。 你可以使用 getStyle() 方法,如以下示例所示:

<s:SolidColorStroke color="{getStyle('color')}" weight="1"/>

你也可以通过使用 FlexGlobals.topLevelApplication 属性访问根应用程序的属性和方法。 更多的信息,请参见 访问应用程序属性

定义皮肤状态

每个有皮肤的组件都有一组可视化的皮肤状态。 例如:按下按钮时,按钮的皮肤显示与down状态相关联的元素。按钮弹起时,该按钮将显示与 up 状态相关联的皮肤元素。

为了使有皮肤的Spark组件和它的皮肤之间的规则有效,你在组件中指定皮肤状态。 然后,在皮肤组件的类中定义状态的外表。

皮肤状态在皮肤类中声明,并假设不同的状态都要显示。 你可以定义皮肤的状态更改时,皮肤是如何变化的。

子类继承其父的皮肤状态。 例如 Button 类定义皮肤状态 updownover,和 disabled。 按钮的子类ToggleButton类除了在按钮中定义的状态还声明了 upAndSelectedoverAndSelecteddownAndSelected状态。

在组件中标识皮肤的状态

宿主部件必须声明它支持的皮肤状态,它只是规则的一部分。 若要标识组件类中的皮肤状态,你可以使用 [SkinState] 元数据标签。 此标记的语法如下:

[SkinState("state")]

在类定义前指定元数据。 下面的示例定义了四个 Button 控件的皮肤状态:

[SkinState("up")] 
[SkinState("over")] 
[SkinState("down")] 
[SkinState("disabled")] 
public class Button extends Component { .. } 

在皮肤类中定义皮肤状态

Spark 皮肤定义规则需要在皮肤类中声明所支持的皮肤状态。 你也可以有选择的定义皮肤类的状态的外表。 即使在一个皮肤类中声明了皮肤状态,也不需要定义其外表。

再皮肤类中定义一个皮肤状态:

1. <states> 标记中声明皮肤状态。

2. 基于组件的状态设置属性的值。 此步骤是可选的,但是如果不定义皮肤状态的外表,那么当该组件进入该状态时,皮肤就不会变化。

若要声明在皮肤类中的皮肤状态,使用 <s:states> 标记作为最外层标签。 每个状态对象对应于一个皮肤状态。

下面的示例定义按钮皮肤类支持的四种状态:

<s:Skin ...> 
<s:states> 
<s:State name="up"/> 
<s:State name="over"/> 
<s:State name="down"/> 
<s:State name="disabled"/> 
</s:states> 
... 
</s:Skin>

你在皮肤类中声明了皮肤状态后,接着你可以定义皮肤状态的外观。 要执行此操作,你通过点符号来指定皮肤状态的属性值 property_name.state_name) over 状态中设置一个 SolidColorStroke 对象的 weight 属性的值,你指定weight.over 属性值如以下示例所示:

<s:SolidColorStroke color="0x000000" weight="1" weight.over="2"/>

也可以通过使用 includeIn excludeFrom 属性指定的属性状态的值。

最常使用的是指定基于状态的样式属性值。 flex 基于组件的当前状态使用样式。 组件当前状态改变时通知组件,因此皮肤可以实时更新皮肤。

当该组件是处于 disabled 状态时,通常设置该组件的 alpha 属性值。 这通常是在皮肤类的在外层标记上设置,下面的 ButtonSkin 类显示了此示例:

<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21" 
alpha.disabled="0.5">

另一个例子是根据其他状态,按钮标签的 alpha 属性更改。 皮肤设置 labelDisplay alpha 属性的值。 当按钮在 up 状态时,标签alpha 1 按钮在 over 状态时,标签有alpha值为0.25,如以下示例所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/StatesButtonExample.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:Button label="Alpha Changes" skinClass="mySkins.MyAlphaButtonSkin"/>
</s:Application>

The executing SWF file for the previous example is shown below:

对于此示例的皮肤类,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/MyAlphaButtonSkin.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 
<fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 </s:Rect>
 
<s:Label id="labelDisplay" 
alpha.up="1"
 alpha.down=".1"
 alpha.over=".25"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
</s:Skin>

基于状态的组件上,你可以设置任何属性。不仅限于样式属性。 例如,你可以基于它的状态更改Button 控件的标签,如以下示例所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/ChangeLabelBasedOnStateExample.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:Button id="myButton" label="Basic Button" skinClass="mySkins.ChangeLabelBasedOnState"/>
</s:Application>

The executing SWF file for the previous example is shown below:

自定义的皮肤类如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/ChangeLabelBasedOnState.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 <fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 <!-- Add this fill to make the "hit area" cover the entire button. -->
 <s:fill>
 <s:SolidColor color="0xFFFFFF"/>
 </s:fill>
 </s:Rect>
 
<s:Label id="labelDisplay"
 text.up="UP" text.over="OVER" text.down="DOWN"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
</s:Skin>

如果确定了的组件上的皮肤状态,但是没有在皮肤类内中声明它, Flex 会引发一个编译器错误,如果设置 [HostComponent] 元数据。 你不需要在皮肤类中设定皮肤状态的外观,但你需要在这种情况下在皮肤类中声明它。

如果你在皮肤类中设置某个状态的样式属性的值时,而该状态没有在宿主组件中标识它,Flex 会引发一个编译器错误。此错误检查有助于强制遵守该组件与皮肤之间的规范。

除了根据条件设置属性值,可以还使用包括或排除方法来将某个图形元素归属某个状态。 如果要这样做,你可以使用 includeIn excludeFrom 属性来定义其状态图形元素的归属。

下面的示例显示了在Button 控件处于 down 状态时,显示一个透明的灰色框:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/IncludeButtonExample.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:Button label="Click Me In the Button Class" skinClass="mySkins.MyIncludeButtonSkin" color="0xCCC333"/>
</s:Application>

The executing SWF file for the previous example is shown below:

自定义的皮肤类如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/MyIncludeButtonSkin.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 <fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 </s:Rect>
 
<s:Label id="labelDisplay"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
 <!-- Highlight (down state only) -->
 <!-- Note that you might need to adjust the radiusX and radiusY properties. -->
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" includeIn="down">
 <s:fill>
 <s:SolidColor color="0x000000" alpha="0.25"/>
 </s:fill>
 </s:Rect>
</s:Skin>

当你使用excludeFrom 属性将某个图形元素排除在某个状态时, Flex 从其父级的子列表中删除它。 该元素将不再被引用。

如果图形元素不在皮肤类中指定 includeIn excludeFrom 属性,图形元素是默认情况下在所有控件的状态使用。

你可以指定多个要包括或排除的状态,它们之间使用逗号分隔。 下面的示例将矩形图形元素排除在宿主组件的 overdown 状态之外:

<s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" excludeFrom="over, down">

只可以在 MXML 中设置 excludeFrom includeIn 属性。 不能在 ActionScript 中设置这些属性的值。

当使用皮肤类后,只要它们的父类是可视的,所有类都支持在皮肤类中使用 includeIn excludeFrom 属性。 这意味着不能对该皮肤文件的根标记中设置这些属性,也不能在分级属性中设置它们。 例如,下面显示一个有效和无效的 includeIn 属性的使用:

<s:states> 
<s:State name="StateA" /> 
</s:states> 
<!—这是一个有效的includeIn属性的使用: --> 
<s:Button> 
<s:label.StateA> 
<fx:String>My Label</fx:String> 
</s:label.StateA> 
</s:Button> 
<!--这是一个无效的includeIn属性的使用,String的父类不是一个可视的对象: --> 
<s:Button> 
<s:label> 
<fx:String includeIn="StateA">My Label</fx:String> 
</s:label> 
</s:Button>

如果你从一个皮肤中排除某些图形元素,组件有时自己调整大小,或者根据状态循环更改它的外观。 例如:如果你对按钮皮肤的 labelDisplay excludeFrom 属性的值设置为 down,该标签在用户单击按钮时将消失。 这样一来,按钮在down 状态时将自行调整大小。下面的示例显示了这种现象:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/HideLabelOnDownExample.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:Button id="myButton" 
skinClass="mySkins.HideLabelOnDownSkin" 
label="This Is A Long Button Label"/>
</s:Application>

The executing SWF file for the previous example is shown below:

自定义皮肤类如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/HideLabelOnDownSkin.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 <fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect 
left="0" right="0" 
top="0" bottom="0" 
width="69" height="20" 
radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 </s:Rect>
 
<s:Label id="labelDisplay"
 excludeFrom="down"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
</s:Skin>

按钮的大小根据标签的内容动态调整。 排除标签导致标签本身从父类中删除。

为了阻止按钮自动调整大小,可以设置alpha.down的属性值为 0 visible.down的属性值为 false ,而不是将整个组件排除在down状态之外,这样标签文本不会消失,按钮也不会自动调整自己,因为标签文本并没有从父类中删除掉,请看下面的示例:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/HideLabelOnDownExample2.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:Button id="myButton" 
skinClass="mySkins.HideLabelOnDownSkin2" 
label="This Is A Long Button Label"/>
</s:Application>

The executing SWF file for the previous example is shown below:

自定义皮肤类如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/HideLabelOnDownSkin2.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 <fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect 
left="0" right="0" 
top="0" bottom="0" 
width="69" height="20" 
radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 </s:Rect>
 
<s:Label id="labelDisplay"
 visible.down="false"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
</s:Skin>

皮肤部件(skin parts

某些组件有多个皮肤部件。 例如: NumericStepper包含一个up按钮,一个down的按钮和text。 这些部件由该组件的声明。 皮肤定义其外观。 组件中定义的部件在皮肤中可以是可选的也可以是必需的。

皮肤部件是皮肤规范的重要组成部份。 他们让组件的实例与皮肤进行交互并且可以将数据压入皮肤文件来定义它的行为。

皮肤部件在Spark皮肤类中不必是最顶层的标签。 他们可以在 MXML 文件中的任何位置。

若要在组件中声明一个皮肤部件,你可以使用 [SkinPart] 元数据。 例如 Button 类在ButtonBase 类中定义皮肤部件:

[SkinPart(required="false")] 
public var labelDisplay:TextBase;

ButtonSkin 类定义了一个标签作为labelDisplay部件:

<s:Label id="labelDisplay" 
textAlign="center" 
verticalAlign="middle" 
maxDisplayedLines="1" 
horizontalCenter="0" verticalCenter="1" 
left="10" right="10" top="2" bottom="2"> 
</s:Label>

在此的示例中, labelDisplay 皮肤部件从技术上说不是必需的 (required="false"),但没有它,Flex 不能在button 控件上绘制一个标签。 required 的属性的默认值为 false Button 类和皮之间的规范规定了当你设置按钮上标签的属性,该值被传递到皮肤文件,如果 labelDisplay 皮肤部件存在,就修改 labelDisplay 皮肤部件的文本值。

部件由其 id 属性标识。 在皮肤类中部件的 id 属性必须与皮肤部件宿主组件中的属性名称相匹配。这将有助于强制遵守皮肤与宿主组件之间的规范。例如:你在组件中使用下面的声明:

[SkinPart(required="true")] 
public var textInput:TextInput;

皮肤类将TextInput实例的 id 属性设置为textInput,如下示例所示:

<s:TextInput id="textInput" ... />

主要有两种类型的皮肤部件: 静态和动态。 静态部件 被皮肤自动实例化。 可能只有一个静态部件的实例。 例如,VScrollBar 类具有四个静态部件: trackthumb incrementButton descrementButton Button 类有一个静态部件: label

动态部件 在需要时被实例化。 动态的部件可以有多个实例。 动态部件定义在皮肤的声明块中,以便可以被使用的皮肤实例化一个或多个实例。例如, 滑块类的DataTip是一个动态的皮肤部件。 在 VSliderSkin HSliderSkindataTip 皮肤部件在声明块中定义。

在你的宿主组件中,可以将动态皮肤部件类型定义为一个 IFactory 例如,滑块类的 dataTip 定义为:

[SkinPart(required="false", type="mx.core.IDataRenderer")] 
public var dataTip:IFactory; 

在运行时加载组件皮肤过程中,SkinnableComponent 基类会找到皮肤的所有部件,分配已找到的部件,如果所需的部件在皮肤内没有定义,则会引发运行时错误。找到被延迟的部件 (因为它们在皮肤中被定义其属性值),因为当组件首次被实例化时,它们是空值。

在组件中使用皮肤类

在定义了一个皮肤后,你可以通过以下方式将它应用到一个组件:

· CSS

· MXML

· ActionScript

可以通过CSS将一个皮肤与一个组件联系起来,在样式表中设置 skinClass属性的值。 你可以使用类型或类选择器将皮肤类应用到一个组件中。

下面的示例通过使用一个类型选择器将 mySkins.NewPanelSkin 类使用到所有的 Panel 容器中:

@namespace s "library://ns.adobe.com/flex/spark"; 
s|Panel { 
skinClass:ClassReference("mySkins.NewPanelSkin"); 
}

下面的示例使用 myButtonStyle 类选择器将 mySkins.CustomButtonSkin 类关联到所有组件中:

.myButtonStyle { 
skinClass:ClassReference("mySkins.CustomButtonSkin"); 
} 
... 
<s:Button label="Spark Button" className="myButtonStyle"/>

若要在 MXML 文件中将皮肤和组件关联到一起,你可以通过行内设定的方法设置 skinClass 属性值。 下面是Panel 容器配置mySkins.NewPanelSkin皮肤的示例:

<s:Panel skinClass="mySkins.NewPanelSkin"/>

使用 CSS 配置皮肤的优点是你可以根据类型或类选择器将某个皮肤应用到所有的特定类型的组件上(例如,所有的按钮)或所有特定的类上 (例如,样式名称为"myButtonStyle"的所有组件)。

CSS 支持继承。 如果使用类型选择器将一个 Button 控件按钮中使用了某个皮肤,该皮肤将所有 Button 控件和 Button 控件的子类(例如:ToggleButton类)都使用该皮肤。 这可能并不是你想要的结果。 如果你将所有Label控件使用某个新皮肤,具有Label标签子组件的组件也将使用该皮肤。 这样一来,你应使用类选择器只将皮肤应用于基本组件。

MXML 中设置一个皮肤类只允许你对组件的实例使用皮肤。

你也可以在ActionScript 中对组件使用皮肤类。 在的组件上调用 setStyle() 方法,并设置 skinClass 样式属性的值。在 setStyle() 方法中,你必须将皮肤转换类。

下面的示例为按钮使用了自定义皮肤类:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/SimpleLoadExample.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>
 import mySkins.*;
 
private function changeSkinClickHandler():void {
 myButton.setStyle("skinClass", Class(MyButtonSkin));
 }
 </fx:Script>
 <s:Button id="myButton" 
label="Click Me" 
color="0xFFFFF" 
click="changeSkinClickHandler()"/>
</s:Application>

The executing SWF file for the previous example is shown below:

自定义皮肤类如下所示:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/mySkins/MyButtonSkin.mxml -->
<s:Skin 
xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:mx="library://ns.adobe.com/flex/mx" 
xmlns:s="library://ns.adobe.com/flex/spark" 
minWidth="21" minHeight="21">
 <fx:Metadata>
 [HostComponent("spark.components.Button")]
 </fx:Metadata> 
<!-- Specify one state for each SkinState metadata in the host component's class -->
 <s:states>
 <s:State name="up"/>
 <s:State name="over"/>
 <s:State name="down"/>
 <s:State name="disabled"/>
 </s:states>
 <s:Rect left="0" right="0" top="0" bottom="0" width="69" height="20" radiusX="2" radiusY="2">
 <s:stroke>
 <s:SolidColorStroke color="0x000000" weight="1"/>
 </s:stroke>
 </s:Rect>
 
<s:Label id="labelDisplay"
 horizontalCenter="0" verticalCenter="1"
 left="10" right="10" top="2" bottom="2">
 </s:Label>
</s:Skin>

在应用程序中使用皮肤类之前,确保已经导入了相应的皮肤类的包。

就像在 CSS 使用皮肤类一样,你可以在ActionScript中队特定组件类型使用皮肤。 在组件的样式声明中调用 setStyle() 方法。 下面的例子展示了对应用程序中的所有按钮使用自定义皮肤:

<?xml version="1.0" encoding="utf-8"?>
<!-- SparkSkinning/ASTypeSelectorLoadExample.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>
 import mySkins.*;
 
private function changeSkinClickHandler():void {
 styleManager.getStyleDeclaration("spark.components.Button").setStyle("skinClass", Class(MyButtonSkin));
 }
 </fx:Script>
 <s:Button id="myButton1" label="Click Me" color="0xFFFFF" 
click="changeSkinClickHandler()"/>
 <s:Button id="myButton2" label="Click Me" color="0xFFFFF" 
click="changeSkinClickHandler()"/>
 <s:Button id="myButton3" label="Click Me" color="0xFFFFF" 
click="changeSkinClickHandler()"/>
</s:Application>

The executing SWF file for the previous example is shown below:

皮肤状态和皮肤部件的文档化

ASDoc 工具支持在 [SkinState] [SkinPart] 的元数据标记之前进行文档描述。

你可以在 [SkinState] 元数据标签上方通过添加注释的方法进行文档描述,如以下示例所示:

/** 
* Up state of the button. 
*/ 
[SkinState("up")]

若要队 [SkinPart] 元数据描述,ASDoc 工具使用来自组件类文件中的变量描述。 你不用在实际的元数据标记上添加的注释,如以下示例所示:

[SkinPart(required="false")] 
/** 
* A skin part that defines the label of the button. 
*/ 
public var labelDisplay:TextGraphicElement;

ASDoc 工具将皮肤状态文档添加到类的“皮肤状态”段。 它将皮肤部件文档添加到类的"皮肤部件"部件的文档段中。

有关 ASDoc 实用程序的详细信息,请参阅 ASDoc

分享到:
评论

相关推荐

    Flex4 Spark皮肤

    Flex4 Spark皮肤详细制作讲解

    Spark皮肤相关文档

    Spark皮肤相关文档,Spark皮肤相关文档,Spark皮肤相关文档

    DataGridSkin 皮肤类

    对spark DataGrid写的皮肤类。主要就是对于datagrid 的column 的label 写皮肤,可以居中显示。

    Spark Studio 编辑开发工具 v2.4.1官方版

    为您提供Spark Studio 编辑开发工具下载,Spark Studio是SparkSource的编辑开发工具,开发人机界面,尤其是嵌入式多屏人机界面交互应用的工具软件,可以轻松管理资源,轻松设计2D场景等!功能介绍 轻松管理资源 以...

    spark skins

    资源包中包含了几个组件的自定义SparkSkin皮肤文件,包括dropDownList和titleWindowskin closeButtonskin共同学习

    Flex4开发的自定义输入框皮肤组件,代图标

    Flex4开发的自定义输入框皮肤组件,代图标,圆角,主要测试Flex4 spark主题下如何自定义组件皮肤。

    flex4权威指南

    Flex 4 提供了多种主题皮肤供用户选择来改变整个项目的主题外观,Skin 的设计也将组件的逻辑元素与可视元素明确的区分开来,引入了新的皮肤和组件架构,被称为 Spark,但是 Flex 4 保留了 Flex3 的命名空间和组件库...

    逸雨清风读秀批量下载 V2.4.5

    1、美化界面,添加皮肤 2、默认下载图书附加页,无需另外复制代码到附加页栏 3、一些细节的优化 使用说明 2013-7-12: 1、首先使用多个帐号登陆读秀获得图书,利用咨询法把全本书分批发到邮箱,复制邮件里读秀给的...

    Flex4权威指南.pdf

    Flex 4 提供了多种主题皮肤供用户选择来改变整个项目的主题外观,Skin 的设计也将组件的逻辑元素与可视元素明确的区分开来,引入了新的皮肤和组件架构,被称为 Spark,但是 Flex 4 保留了 Flex3 的命名空间和组件库...

    flex4 scrollbar

    flex4里引入了sparkSkin, spark包里的可视控件可以通过指定skinClass的值来修改控件的默认皮肤。 下面是一个如何自定义某个scrollbar的外观的例子。

    flex 4实战

    Flex已经从原来构建Flash应用程序的一种方式发展成为 一个丰富的体系。Flex 4中引入了新的UI组件,提供了更好 的性能监控,并且大大提高了编译速度。...◆ 使用主题和皮肤使应用程序具有独特的外观

    Flex4实战完整版(2)

    即使读者刚刚接触Flex,在阅读本书之后也可以使用新增的spark组件、数据服务、图表设计、特殊效果等,使自己的应用程序广受欢迎。《Flex4实战》的读者需要具备基本的开发技能,但是不要求以前使用过Flex。主要内容:...

    Flex4实战完整版(1)

    即使读者刚刚接触Flex,在阅读本书之后也可以使用新增的spark组件、数据服务、图表设计、特殊效果等,使自己的应用程序广受欢迎。《Flex4实战》的读者需要具备基本的开发技能,但是不要求以前使用过Flex。主要内容:...

    《Flex 4实战》.pdf

    即使读者刚刚接触Flex,在阅读《Flex 4实战》之后也可以使用新增的spark组件、数据服务、图表设计、特殊效果等,使自己的应用程序广受欢迎。《Flex 4实战》的读者需要具备基本的开发技能,但是不要求以前使用过Flex...

    Flash轻量级UI框架FlexLite.zip

    从Flex庞大的框架体系中剥离出针对游戏开发使用的轻量级UI框架,移除或精简掉所有不常用且损耗性能的部分,仅保留Spark的皮肤分离机制和自动布局功能,为游戏开发设计一个更加高效的UI工作流。 标签:...

    PHP 即时通讯项目

    &gt; 可更换界面皮肤,皮肤样式文件 采用 类似 CSS 的语法,便于美工独立工作。 &gt; 纯 PHP 实现,从 通讯协议 到 图形界面,全部都由 PHP 开发,如果你正好是一名 PHP 程序员,你可以驾轻就熟地在 JJ 之上进行二次开发...

    JeCat-Jabber PHP开源即时通讯软件[Version 0.1]

    &gt; 可更换界面皮肤,皮肤样式文件 采用 类似 CSS 的语法,便于美工独立工作。 &gt; 纯 PHP 实现,从 通讯协议 到 图形界面,全部都由 PHP 开发,如果你正好是一名 PHP 程序员,你可以驾轻就熟地在 JJ 之上进行二次开发...

Global site tag (gtag.js) - Google Analytics