级别: 初级 Dan Orlando, 软件架构师, Vision Media Group
2009 年 8 月 24 日 利用已经构建到 Adobe® Flex™
框架内的 CSS 的强大功能。本文提供了在 Flex 内开始使用 CSS 所需的信息,也提供了在使用 Flex 设计和开发用户界面时加速工作流的提示和技巧。
Flex 最为强大的特性之一是其包含的极大的设计灵活性。这些灵活性大部分可归功于 Adobe 用 Flex 实现 CSS。以我为例,我最近为一个新的 Adobe AIR™ 应用程序担任高级 UI 设计员,在我向全球 160,000 个用户正式发布第一个公开发布版的若干天前,我收到了大量设计更改请求。虽然很多开发人员都会将这些最后一分钟的请求看作是让人头痛的事,我却能在不足 20 分钟内完成这些更改并将其放入版本控制,而这完全得益于 Flex 和 CSS 的强大功能。
 |
常用缩略语
- UI:用户界面
- W3C:World Wide Web Consortium
|
|
我将 CSS 与 Flex 的使用看作是 UI 开发内的一种利用形式。通过我在 UI 开发中积累的经验,我已经学会了为一些必然性做预期和准备。其中一个必然性是不管您在之前做了什么样的计划,项目的设计与功能需求都会在整个开发周期内随时发生变化。这是基于团队环境做大规模应用程序开发时的游戏规则,要在游戏中取胜,最好的方法就是预先判断出所有玩家的动向,然后再提前相应做好自己的定位。学会了灵活使用这个开发技巧后,您就可以立于不败之地,那时再去击打一个移动目标就变得轻松多了。Flex 的性能,比如与 CSS 的集成,恰巧可以让您这么做,正是因为这一点,我才迷上了用 Flex 进行开发。
我的目标是在您读完本文后,您也能够通过 Flex 去充分利用 CSS 的强大功能,并能作为一名精通 Flex UI 的开发者战无不胜。如果您已经是一个 Flex 爱好者,那么我希望您能通过本文学会新的通过 Flex 使用 CSS 的技巧 — 特别是对于企业级应用程序。
为何要使用 CSS?
大多数面向对象的设计模式都将设计逻辑与行为功能分离开来。由于 Adobe ActionScript™ 是一种面向对象的语言,因此它也就自然而然地要遵守这些面向对象的编程(OOP)约定。这么做的好处包括灵活性、保持应用程序易于维护、代码重用和更好的性能。
在 Web 设计界,CSS 是一种标准,用来封装组成 Web 站点的代码。考虑到 CSS 的功能和成熟性,很多有经验的 Web 设计人员都力求用 CSS 实现 Web 站点的设计和布局属性。其结果是可以获得对站点观感的更多的控制和更好的灵活性。CSS 在三、四年前就已经十分流行,那时候 Web 开发人员开始意识到如果 Web 站点的设计能够独立于该站点的行为功能,那么站点的设计在不破坏或者不会对该站点的行为代码产生负面影响的同时,可以很容易地被修改。这也推动了模板的迅速发展、对相同代码库的皮肤设置以及重新进行皮肤设置。比如,我热衷于为我的博客网站使用 WordPress。有成千上万的人都在使用相同的开源代码库来支撑其博客站点,而很多时候,您遇到的站点都是构建在 WordPress 之上的,而您却往往察觉不到这一点,这完全得益于其通过使用 CSS 对代码和设计进行的成功分离。
Flex 内的 CSS
首先,对于具有 Web 设计背景的人,最为重要的是要理解 Flex CSS 并不遵循与 W3C CSS 规定相同的约定。在 W3C CSS 版本 2.0 中被用来分离单词的连字符(-)并未用作 Flex 实现内的代码约定的一部分。相反,CSS 的 Flex 实现使用了驼峰式大小写。比如,W3C CSS2 规范内的 vertical-center 对等于 Flex CSS 内的 verticalCenter。如果您已经在使用了驼峰式大小写的编程语言内进行过编程,那么,这非常容易习惯。好的消息是 CSS 2.0 规范内可用的大部分内容在 Flex
CSS 实现内也可用。并且,CSS 的 Flex 实现是在 CSS 2.0 W3C 标准上的显著扩展,提供了额外的、对 Flex 组件惟一的样式属性。
维护样式:组件与样式属性
在开始创建 Flex CSS 样式表之前,我建议您首先考虑您想要如何实现样式。出于简单性的考虑,我向您展示了四种声明样式的基本方法:
- 通过组件的类名。 通过将组件的类名作为样式名来设置组件的样式:
TitleWindow {
borderColor: #f7f7f7;
borderAlpha: 1;
borderThicknessLeft: 0;
borderThicknessTop: 0;
borderThicknessBottom: 0;
borderThicknessRight: 0;
cornerRadius: 0;
headerHeight: 0;
highlightAlphas: 1, 1;
headerColors: #f7f7f7, #f7f7f7;
footerColors: #f7f7f7, #f7f7f7;
backgroundColor: #f7f7f7;
dropShadowEnabled: true;
}
|
- 通过一个惟一的样式名。通过使用一个惟一的样式名来声明样式。请确保在名字之前使用一个句点并使用驼峰式大小写约定:
.altText
{
fontFamily: TVNordEFCEOP-RegularCon;
fontSize: 18;
color: #FFFFFF;
}
|
- 通过一个组件外加一个样式名。当同一个组件需要有多种设计时(这对于具有多个视图状态的应用程序很常见),可以设置组件的样式名。这种方法还确保了只有特定的组件才可以分配到特定的样式:
Text.bigYellowText
{
color:#EFB526;
fontSize:36;
fontWeight:Bold;
}
|
- 通过全局选择器。全局选择器 是一种特殊的选择器,它能够影响包含属性集的应用程序内的每一个组件。比如,我可以将包含有
cornerRadius 样式属性的所有显示对象组件的 cornerRadius 样式属性设置为 4,如下所示:
global
{
cornerRadius: 4;
}
|
样式优先权
虽然全局选择器基本上设置的是一个属性的默认值,该值很容易被覆盖。比如,如果我在内联(inline)或在我的 CSS 文件内将 Button 组件的 cornerRadius 属性设置为 0,它将优于我已经指定的
4 这一全局默认设置;因此,所有我的 Button 组件都将包含一个值为 0 的 cornerRadius 属性。而且,我将通过创建一个额外的样式来覆盖 4 这一全局设置和
0 这一 Button 设置:
Button.altCornersButton
{
cornerRadius: 8;
}
|
在 Flex 内应用样式
选择用 Flex 实现 CSS 的方法必须基于环境和条件。在考虑设计实现的可用选项时,最好是从较高的层次审视应用程序。如下的这些方法是用 Flex 实现 CSS 时最为常用的。
设置一个实例(内联)上的样式
扩展了 Flex UIComponent
基类的 Flex 组件允许作为内联属性设置常见样式
— 换言之,即在 MXML 组件声明标签内(参见 清单 1)。一个显示对象的布局属性通常对该对象惟一,所以常常能够看到某个组件被显式地设置了如下这些属性之一:x、y、height、
width、top、right、left、bottom、horizontalCenter、
verticalCenter、horizontalAlign 和 verticalAlign。
清单 1. 用 MXML 作为某个组件实例的属性设置样式
<mx:Button id="volumeIcon" cornerRadius="0" alpha="0.9"
verticalCenter="0" enabled="true" toolTip="Volume Control"
click="toggleVolumeControl();" />
|
清单 1 展示了设置样式属性的一个函数示例,这些属性对 id 值为 volumeIcon 的 Button 组件的这个特定实例是惟一的。由于我知道它是惟一一个需要这些特定样式值的按钮,因此我已经显式地设置了此特定按钮的 cornerRadius、alpha 和
verticalCenter。
设置 MXML 组件标签上的样式属性的一条经验是,只有在知道所设置的样式值特定于该组件的情况下才以这种方式设置此属性。比方说,您的应用程序要求一个容器能够垂直堆叠显示对象而不在其间留空隙。同时,您知道应用程序内的其他 VBox
容器则确实需要显示对象之间有空隙。在这种情况下,您应该在 VBox 组件的该实例上显式地设置 verticalGap 属性,如 清单 2 所示。
清单 2. 在 VBox 容器组件的这个实例上 verticalGap 被显式地设为 0
<mx:VBox id="myVBox" verticalGap="0"
x="15" y="15" width="100%" height="100%">
(...)
</mx:VBox>
|
在 MXML 内嵌入 CSS
该方法所涉及到的是用 <mx:Style/> 标签将样式或资源直接嵌入到一个 MXML 文件内。出于实用的目的,现在需要在其中直接将样式信息嵌入到 MXML 文件的实例很少。最重要的是要认识到如果应用程序包含很多被嵌入的 CSS,那么随着应用程序的增长,设计将越来越难以维护。认识到这一点,在使用这种方法时,要十分慎重,只有在需要的时候才使用它。清单 3 提供了嵌入样式声明的一个例子,该声明应该保留在一个外部 CSS 文件内以便获得更好的代码可维护性。
清单 3. 将样式直接嵌入到 MXML 应用程序文件内
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showFlexChrome="false"
borderStyle="none"
keyUp="{this.onKeyStrokeEvent(event);}">
<mx:Style>
.bGroup {
borderSides:"left,bottom,right";
borderStyle:"solid";
borderColor:#6d6f71;
borderLeftThickness:3;
borderRightThickness:3;
borderBottomThickness:1;
dividerColor:#6d6f71;
dividerThickness:3;
}
</mx:Style>
<mx:Script>
<![CDATA[
(...)
|
不过,这并不是说它将永远不会发生。清单
4 就是我基于 Flex AplicationControlBar 而为我的应用程序所构建的一个向下扩展(scaled-down)的组件。在所提供的设计内,控制栏内的每个按钮实际上都是一个简单的文本单词,看上去更像是一个链接,而非按钮。此外,所有这些单词链接之间都有一个小的 bullet 分隔符。由于我已经有了整个应用程序的设计,因此我知道这种 bullet 分隔符是应用程序主控制栏所特有的,在任何其他地方都不会出现。最为重要的是,由于 bullet 在同一个组件内出现若干次,因此非常有必要将此图像作为其自己的私有类嵌入到这个 MXML 文件内,以便我能从放置在这些链接之间的每个图像控件中绑定它。否则,结果很有可能是正在创建的同一个图像却具有多个实例,这是对系统资源的一种浪费。
清单 4. 直接嵌入一个图像
<?xml version="1.0" encoding="utf-8"?>
<mx:ApplicationControlBar xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Embed(source="assets/bullet_black.png")]
[Bindable]
private var bullet:Class;
]]>
</mx:Script>
<mx:HBox x="10" y="10" id="hbox" horizontalGap="10" width="350">
<mx:LinkButton label="Help" styleName="appBarButton"/>
<mx:Image source="{bullet}" />
<mx:LinkButton label="About" styleName="appBarButton"/>
<mx:Image source="{bullet}" />
<mx:LinkButton label="Minimize" styleName="appBarButton" />
<mx:Image source="{bullet}" />
<mx:LinkButton label="Quit" styleName="appBarButton"/>
</mx:HBox>
</mx:ApplicationControlBar>
|
外部样式表
一个 Flex 或 AIR 应用程序在其源代码目录的根部具有一个 MXML 文件,应用程序可以基于 Application 类(Flex)或 WindowedApplication 类(AIR)。这个文件就是默认的 MXML 应用程序文件,开始于 <mx:Application/> 或 <mx:WindowedApplication/>。应用程序的样式表源代码应该立即出现在应用程序基类声明之后(参见 清单 5)。
清单 5. 在除主应用程序 MXML 文件之外的任何文件内声明样式表都会导致错误
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
showFlexChrome="false"
dropShadowEnabled="false"
borderStyle="none"
applicationComplete="{this.appInit(event);}"
>
<mx:Style source="com/passalong/assets/RED_SKIN_MAIN.css"/>
<mx:Script>
< | 
|  | Dan Orlando 是一名软件架构师,擅长于客户端涉及 Flex、AIR 和 ActionScript 的富客户机-服务器应用程序。他使用过多种 Web 服务协议和服务器端语言。Dan 是 Vision Media Group 的共同创办人,还在 (RED)WIRE 团队担任过高级 UI 开发员。 |
对本文的评价
|