4 October 2009
本文假设您熟悉 Flex 3 Framework。
中级
Flex 4(代码名:Gumbo) 发行版在 Flex 3 基础上做出重大改动。Flex 4 引入了一个新的组件和外观架构。但是作为 Flex 3 开发人员,您在使用 Flex 4 编译 Flex 3 应用程序时可能不会遇到太多难题,因为新发行版的目的之一是保持与 Flex 3 的向后兼容性。
在本文中,我将简要概述 Flex 4 的主要目的和架构区别并介绍组件、布局、状态使用和效果方面的变化。我还将针对使用 Flex 4 编译 Flex 3 应用程序时遇到的情况回答一些提问。本文无法涵盖 Flex 4 的所有新增功能。相关信息请阅读 Flex 4 新增功能一文。
本文中的术语 MX 组件是指 Flex 3 原先包含的组件。术语 Spark 组件是指 Flex 4 中的一套新组件。
将 Flex 3 应用程序迁移到 Flex 4 时,步骤并不复杂。除了一些缺陷修复以及默认主题稍有变化,您的应用程序通常可以像 Flex 3 中那样正常运行(或更好)。但您必须注意几点。
请务必针对 Flash Player 10 进行编译。Flex 4 SDK 需要 Flash Player 10 支持。
CSS 字体选择器将 Flex 类命名为 style。例如,以下是 Button 和 DateField 的字体选择器:
Button {
cornerRadius: 10;
}
DateField {
color: #780800;
}
从 Flex 4 SDK 开始,当应用程序使用字体选择器时,需要命名空间。如果您只在 Flex 应用程序中使用 MXML 2006 命名空间,请将以下默认命名空间声明添加到 CSS 中:
<mx:Style>
@namespace "http://www.adobe.com/2006/mxml";
…
</mx:Style>
如果在应用程序中使用多个命名空间,您需要在 CSS 中提供各个命名空间。有关示例,请参阅本文稍后部分中的 Flex 4 中的命名空间与包。
此外,如果应用程序使用 StyleManager.getStyleDeclaration("Button") 等方法,字体选择器必须包含它的包。例如,对 getStyleDeclaration() 的调用将改为 StyleManager.getStyleDeclaration("mx.controls.Button")。
Flex 3 (MX) 组件的默认主题现在是 Spark 主题。因此,当您使用 Flex 4 SDK 编译应用程序时,它的外观和大小可能有所不同。但是,如果要使用 Flex 3 的外观,您还是可以做到的,因为 Flex 4 包含 Flex 3 的 Halo 主题。要使用 Halo 主题进行编译,您可以使用附加编译器参数 -compatibility-version=3.0。在 Flash Builder 4 中,您可以在“Properties Panel”(属性面板)中这样做。在“Properties Panel”(属性面板)中,选择“Flex Compiler”(Flex 编译器)并单击“Use Flex 3 compatibility mode”(使用 Flex 3 兼容性模式)复选框(请参阅图 1)。
您也可以通过“Properties”(属性)->“Flex Theme”(Flex 主题)面板将主题从默认 Spark 主题改为 Halo。在“Flex Theme”(Flex 主题)面板中,单击 Halo 主题(请参阅图 2)。
如果您选择使用新的 Spark 主题,请注意许多可用于 Halo 主题的样式无法用于 Spark 主题。Spark 主题只支持数量有限的样式。要了解 Spark 外观可以使用哪些样式,您应当参阅 ASDoc。将为每个组件列出的各个样式指定一个“主题”。如果未指定主题,表示该样式既可用于 Halo,也可用于 Spark 主题。Flex 4 还加入了一种设计用于快速模型的线框外观。线框主题不支持样式更改。
除了主题更改外,Flex 4 应用程序的默认预下载器也已经改为 mx.preloaders.SparkDownloadProgressBar。这个更轻量级的预下载器可以缩短一些启动时间。如果要使用 Flex 3 预下载器,您只需更改一行代码。在 Application 标签中添加以下内容:preloader="mx.preloaders.DownloadProgressBar"。
如果要将应用程序从 Flex 3 迁移到 Flex 4 ,我不建议将各个 Flex 3 MX 组件替换为它们对应的 Flex 4 组件。这样投入时间可能并不是一个好方法。您应当为新的应用程序转而使用 Flex 4 组件架构。
在 Flex 3 中,自动库位于 {sdk}/frameworks/libs 中,而在 Flex 4 中,它位于 {sdk}/frameworks/libs/automation 中。用户应当确保 frameworks/libs 中没有自动库副本。
Flex 4 SDK 的重要主题之一是“用心设计”。这个目标涉及在设计人员和开发人员之间创造一个更顺畅的工作流程。为了帮助实现这一点,该框架将组件可视部分与其剩余行为明确划分开。在 Flex 3 中,组件的代码包括以其行为、布局和可视变化为中心的逻辑。在 Flex 4 中,组件被划分为不同的类,各个类负责处理特定的行为。
Gumbo 架构文档中的说明如下:
“主组件类,即类名与组件的 MXML 标签名匹配的那个类封装了组件的核心行为。这包括定义组件调度的事件、组件表示的数据、接通作为主组件组成部分的任何子组件以及管理和跟踪内部组件状态(稍后我们将详细讨论状态)。
与之相应的组件类是一个外观类,它负责管理与组件的可视外观相关的一切内容,包括图形、布局、表示数据、更改不同状态中的外观以及从一个状态过渡到另一个状态。在 Halo 模型中,Flex 组件外观是只负责组件的某个图形部分的资源。更改组件外观的任何其他方面,如布局或状态可视化,需要将组件子类化并直接编辑 ActionScript 代码。在 Gumbo 模型中,所有这一切都在外观类中以声明方式进行定义,并且主要通过名为 FXG 标签的新图形标签进行定义。”
要进一步了解 Flex 4 中新的图形标签,您可以阅读 FXG 文档。
作为上述架构的示例,您可以参考 spark.components.Button 类的代码。这个类只包含以组件行为为中心的逻辑。在外观类 spark.skins.spark.ButtonSkin 中定义这个组件的所有可视部分。
考虑到性能,Flex 4 SDK 为开发人员提供了构造块,可供他们根据需要选择功能。默认情况下,关闭并非所有应用程序都需要的重量级功能,如滚动和虚拟化。
在将 Flex 3 类原封不动地保留在同一 mx.* 包中的同时,Flex 4 SDK 为组件、核心类、效果、滤镜、布局、基元、外观和 utils 引入了 spark.* 包。
Flex 4 SDK 提供一套新的组件和效果,它们与 Flex 3 组件共享许多相同类名。为了避免 MXML 中出现名称冲突,Flex 4 SDK 随附四个独特的命名空间:MXML 2006、MXML 2009、Spark 和 Mx。
MXML 2006:之前版本的 Flex 中使用的旧版 MXML 语言命名空间。使用 Flex 4 beta 编译的 Flex 3 应用程序可以继续使用这个命名空间。
URI:http://www.adobe.com/2006/mxml
默认前缀:mx
MXML 2009:新的 MXML 语言命名空间。这纯粹是一个语言命名空间,不包含组件标签。
URI:http://ns.adobe.com/mxml/2009
默认前缀:fx
Spark:这个命名空间包含所有新的 Spark 组件。它应当与 MXML 2009 语言命名空间一起使用。
URI:library://ns.adobe.com/flex/spark
默认前缀:s
MX:这个命名空间包含所有 MX 组件。它应当与 MXML 2009 语言命名空间一起使用。
URI:library://ns.adobe.com/flex/mx
默认前缀:mx
以下是使用 MXML 2009、Spark 和 Halo 命名空间创建一个简单的 Flex 4 beta 应用程序的简明示例。它使用一个 MX DateChooser 和一个 Spark Button。
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<mx:DateChooser id="main_calendar" x="20" y="20"/>
<s:Button label="submit" x="220" y="20"/>
</s:Application>
Flex 4 SDK 还在 CSS 中加入了多命名空间支持。如果将 MXML 2009、Spark 和 MX 命名空间与字体选择器一起使用,您需要在 CSS 定义中定义一组命名空间以避免名称冲突。
以下是一个将字体选择器用于 MX 和 Spark 组件的 CSS 示例:
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
s|Button {
color: #FF0000;
}
mx|DateChooser {
color: #FF0000;
}
</fx:Style>
在 Flex 4 SDK 发布之前,Flex 语言允许 Application 根标签包含可视子代和非可视子代。可视子代与 addChild() 一起添加到 Application,非可视子代则作为属性声明。随后,表示新属性声明的非可视子代不可以作为 Application 的直接子代。您可以将这些非可视子代添加到 <fx:Declarations> 标签下。这包括效果、验证程序、格式化程序、数据声明和 RPC 类等非可视子代。以下是一个简短的示例:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<s:Fade id="fadeEffect" target="{targetButton}" alphaFrom="1" alphaTo="0" />
</fx:Declarations>
<s:Button id="targetButton" />
<s:Button label="play effect" click="fadeEffect.play()" x="80" />
</s:Application>
如前所述,Flex 4 SDK 引入了许多使用新架构的新组件类,它们应当可以令外观和其他自定义操作更简单。下表列出了 Flex 3 MX 组件及其 Flex 4 Spark 对应组件:
| Flex 3 MX 组件 | Flex 4 beta Spark 组件 |
|---|---|
| mx.controls.Button | spark.components.Button |
| mx.controls.ButtonBar | spark.components.ButtonBar |
| mx.controls.CheckBox | spark.components.CheckBox |
| mx.controls.ComboBox | spark.components.DropDownList(不可编辑) |
| mx.controls.HorizontalList | spark.components.List(带一个 HorizontalLayout) |
| mx.controls.HRule | spark.primitives.Line |
| mx.controls.HScrollBar | spark.components.HScrollBar |
| mx.controls.HSlider | spark.components.HSlider |
| mx.controls.Image | spark.primitives.BitmapImage(不支持外部图像) |
| mx.controls.LinkBar | spark.components.ButtonBar(带一个自定义外观) |
| mx.controls.LinkButton | spark.components.Button(带一个自定义外观) |
| mx.controls.List | spark.components.List |
| mx.controls.NumericStepper | spark.components.NumericStepper |
| mx.controls.RadioButton | spark.components.RadioButton |
| mx.controls.RadioButtonGroup | spark.components.RadioButtonGroup |
| mx.controls.TextArea | spark.components.TextArea |
| mx.controls.TabBar | spark.components.TabBar |
| mx.controls.TextInput | spark.components.TextInput |
| mx.controls.TileList | spark.components.List(带一个 TileLayout) |
| mx.controls.ToggleButtonBar | spark.components.ButtonBar |
| mx.controls.VideoDisplay | spark.components.VideoPlayer |
| mx.controls.VRule | spark.primitives.Line |
| mx.controls.VScrollBar | spark.components.VScrollBar |
| mx.controls.VSlider | spark.components.VSlider |
| mx.core.Application | spark.components.Application |
| mx.core.Window | spark.components.Window |
| mx.core.WindowedApplication | spark.components.WindowedApplication |
| mx.containers.ApplicationControlBar | spark.components.Application(带 controlBarContent) |
| mx.containers.Canvas | spark.components.Group |
| mx.containers.ControlBar | spark.components.Panel(带 controlBarContent 属性) |
| mx.containers.HBox | spark.components.HGroup |
| mx.containers.Panel | spark.components.Panel |
| mx.containers.Tile | spark.components.Group(带一个 TileLayout) |
| mx.containers.VBox | spark.components.VGroup |
Adobe 鼓励您与 Spark 组件一起使用 MX 组件和容器。由于 Adobe 在同一基类 (UIComponent) 上构建组件,Spark 与 MX 之间应当可以实现全面的可互操作性。下表列出了目前没有 Spark 直接等效类的组件和容器。
| Flex 3 类,没有直接的 Flex 4 beta 对应类 |
|---|
| mx.controls.Alert |
| mx.controls.ColorPicker |
| mx.controls.DataGrid |
| mx.controls.DateChooser |
| mx.controls.DateField |
| mx.controls.Menu |
| mx.controls.MenuBar |
| mx.controls.PopUpButton |
| mx.controls.PopUpMenuButton |
| mx.controls.ProgressBar |
| mx.controls.RichTextEditor |
| mx.controls.Tree |
| mx.containers.Accordion |
| mx.containers.DividedBox |
| mx.containers.Form |
| mx.containers.Grid |
| mx.containers.TabNavigator |
| mx.containers.TitleWindow |
| mx.containers.ViewStack |
要将 MX 导航器(ViewStack、Accordion、TabNavigator)用于 Spark 组件,导航器的子代应当是一个 NavigatorContent 组件。否则,您无法在 MX 导航器中使用 Spark 基元。此处是一个示例:
<mx:ViewStack id="vs" selectedIndex="{tb.selectedIndex}">
<s:NavigatorContent label="bar">
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Label text="bar" />
<s:TextInput />
</s:NavigatorContent>
</mx:ViewStack>
Flex 4 将状态功能升级为一个全面的 MXML 语言功能。因此,您可能会发现状态更灵活、更直接。新的状态语法内联程度更高,允许在上下文中指定状态特定变化。以下是 Flex 4 语法中的主要区别:
AddChild 和 RemoveChild。您必须使用 includeIn 和 excludeFrom 属性在组件上定义组件在特定状态中的角色。 在以下 Flex 3 示例中,仅当文档的 currentState 为 submitState 时,才使用状态包含一个 Button 并删除一个 TextInput。对于较复杂的状态,这种方法可以做到十分详细。
<mx:states>
<mx:State name="submitState" basedOn="">
<mx:AddChild relativeTo="{loginForm}" >
<mx:Button label="submit" bottom="10" right="10"/>
</mx:AddChild>
<mx:RemoveChild target="{firstTextInput}"/>
</mx:State>
</mx:states>
<mx:TextInput id="firstTextInput" />
<mx:Canvas id="loginForm" />
以下是一段使用 includeIn 和 excludeFrom、更简单的 Flex 4 代码。
<s:states>
<s:State name="submitState" />
</s:states>
<s:TextInput id="firstTextInput" excludeFrom="submitState" />
<s:Group id="loginForm" >
<s:Button label="submit" bottom="10" right="10" includeIn="submitState"/>
</s:Group>
SetProperty、SetStyle 和 SetEventHandler 已替换为新的点语法,它允许您限定具备特定状态标识符的 MXML 属性值。 在以下 Flex 3 示例中,代码为 submitState 中的一个 Button 定义了属性、样式和事件。
<mx:states>
<mx:State name="submitState" basedOn="">
<mx:SetProperty target="{submitButton}" name="label" value="submit" />
<mx:SetStyle target="{submitButton}" name="textDecoration" value="underline"/>
<mx:SetEventHandler target="{submitButton}" name="click" handler="trace('done');"/>
</mx:State>
<mx:State name="clearState" basedOn="">
<mx:SetProperty target="{submitButton}" name="label" value="clear" />
<mx:SetEventHandler target="{submitButton}" name="click" handler="emptyDocument()" />
</mx:State>
</mx:states>
<mx:Button id="submitButton" />
在 Flex 4 中,代码如下:
<s:states>
<s:State name="submitState" />
<s:State name="clearState" />
</s:states>
<s:Button label.submitState="submit" textDecoration.submitState="underline"
click.submitState="trace('done')" click.clearState="emptyDocument()"
label.clearState="clear" textDecoration.clearState="none"/>
此外,各个组件现在支持外观类中定义的一组状态,这使得根据组件状态应用可视变化更加简单。例如,如果查看 Spark Button 的外观,您会发现已定义以下状态:
<s:states>
<s:State name="up" />
<s:State name="over" />
<s:State name="down" />
<s:State name="disabled" />
</s:states>
ButtonSkin 类定义了各个状态中 Spark Button 在可视方面的变化。
以上只是简要介绍了新的 Flex 4 beta 状态语法。有关更多详细信息,请参阅增强的状态文档*。
Flex 4 的效果架构改进显著。虽然 MX 效果只能用于不基于 UIComponent 的控件,Spark 效果可用于任何目标,包括框架中的新图形基元。所有这些效果类都包含在 spark.effects.* package 中。由于 Spark 效果可用于 MX 组件、Spark 组件和图形基元,Adobe 建议您在今后的应用程序中使用 Spark 效果类。
我并未赘述这一问题,因为您可以通过 Chet Haase 的 Adobe Flex 4 中的效果一文了解效果类中新增功能的更多详细信息。
之前的 Flex 版本在各个控件中定义组件和容器布局。因此,List、TileList 和 HorizontalList 等组件都共享布局以外的相同功能。而它们的布局逻辑仍在这些组件类中进行定义。在 Flex 4 中,布局已与组件剥离开来。现在,Application、List、ButtonBar 和 Panel 等 Spark 组件可以通过声明方式定义布局。在所有组件中,Group 类负责管理包含,而 Group 的子代的布局则委派到相关的布局对象。布局除了 FXG 图形基元,还支持 Spark 和 MX 组件。甚至可以在运行时更改布局。
作为开发人员,您可以轻松编写自定义布局并将它们切入或切出个别组件。以下是定义垂直 List、水平 List 和拼贴 List 的一个示例。
垂直 List(Spark List 的默认布局是 VerticalLayout):
<s:List />
水平 List:
<s:List>
<s:layout>
<s:HorizontalLayout />
</s:layout>
</s:List>
拼贴 List:
<s:List>
<s:layout>
<s:TileLayout />
</s:layout>
</s:List>
如前所述,Flex 4 架构旨在为开发人员提供构造块,供他们根据需要选择功能。默认情况下,关闭虚拟化和滚动。要增加 Group 上的滚动栏选项并开启虚拟化,您需要:
useVirtualLayout 设为 trueScroller 组件添加到 Group。以下是对 Spark Panel 使用虚拟化和滚动的一个示例:
<s:Panel title="Horizontal Panel" width="300" height="220" left="20" top="20">
<s:Scroller width="100%" height="100%">
<s:Group>
<s:layout>
<s:HorizontalLayout useVirtualLayout="true" />
</s:layout>
<s:TextInput />
<s:Button label="clear" />
<mx:DateChooser />
<s:Button label="submit" />
</s:Group>
</s:Scroller>
</s:Panel>
有关 Flex 4 中的所有布局增强(包括对变换的更好支持)的更多信息,请参阅 Spark 布局文档。
所有 Spark 组件都使用 Flash Player 10 中的新文本引擎。这些新类为控制文本度量标准、垂直文本以及连字、双向文本等字形元素提供了低级支持。Flex 4 SDK 在使用文本的所有 Spark 组件中用到了这一功能。有关 Flex 4 提供的文本基元和文本组件的更多信息,请参阅 Spark 文本基元规范中的“文本基元”部分。
Spark 组件现在还使用 Flash Player 10 和 AIR 1.5 中的 DefineFont4 嵌入字体格式。默认情况下,MX 组件不使用 DefineFont4。将 Spark 和 MX 组件混合在一个应用程序中并嵌入字体时,这会造成一些开销。如果要对所有组件使用同一种嵌入字体,您需要为项目添加一个额外的主题编译器参数。借助这个新主题,MX 和 Spark 组件都将使用同一个 DefineFont4 字体引擎。在“Properties”(属性)->“Flex Compiler”(Flex 编译器)面板中选中“Use Flash Text Engine in MX components”(在 MX 组件中使用 Flash 文本引擎)选项,即可添加这个编译器参数。(请参阅图 3 。
在 Flex 4 应用程序中使用文本时,我建议使用 Flex 4 的三个 Spark 文本组件之一。它们都使用 flash player 的新文本引擎,并且为设备字体和双向文本提供更高质量的文本、字距微调和旋转。以下是 Flex 4 中提供的文本组件之间的区别。
| 多行 | 截断 | 可选择 | |
|---|---|---|---|
| mx.controls.Label | 否 | 是 | 是 |
| mx.controls.Text | 是 | 否 | 是 |
| spark.components.Label | 是 | 是 | 否 |
| spark.primitives.RichEditableText | 是 | 是 | 否 |
| spark.primitives.RichText | 是 | 否 | 是 |
| 可编辑 | HTML 格式化 | 滚动 | |
|---|---|---|---|
| mx.controls.Label | 否 | 是 | 否 |
| mx.controls.Text | 否 | 是 | 否 |
| spark.components.Label | 否 | 否 | 否 |
| spark.primitives.RichEditableText | 否 | 是 | 否 |
| spark.primitives.RichText | 是 | 是 | 是 |
与 Flex 3 一样,您可以使用其他编译器参数编译应用程序:
-compatibility-version=3.0.0.
这个编译器参数允许应用程序使用某些 Flex 3 行为,而不是新的 Flex 4 行为。要获得 Flex 4 中支持使用 -compatibility-version 参数的向后兼容性变化的完整列表,请参阅向后兼容性文档。
注意:调用 Flex 3 兼容性时,无法选择性地保留一个 Flex 4 行为变化子集。如果使用参数 -compatibility-version=3.0.0 进行编译,您将获得文档中描述的所有 Flex 3 行为。
从 Flex 3 迁移到 Flex 4 有可能没那么痛苦。这个框架旨在尽可能地向后兼容。并且,当您熟悉新架构后,您会发现它其实更“灵活”!有关 Flex 4 功能的更多信息,请访问 Web 帮助。
Flex User Forum |
More |
Flex Cookbook |
More |
| 02/09/2012 | Using Camera with a MediaContainer instead of VideoDisplay |
|---|---|
| 02/08/2012 | Digital Clock |
| 01/20/2012 | Skinnable Transform Tool |
| 12/12/2011 | Date calculations using 'out-of-the-box' functions |