Flex移动皮肤-第一部分:增强的皮肤功能基础
2012-04-18 13:21
411 查看
Flex 4.5提供的移动增强的皮肤特性,支持触摸交互、性能优良,并且考虑到了内存占用问题。尽管目前市场上有不少性能优异的设备,但典型的Spark皮肤(包括Flex 4引入的默认皮肤)却没有能够在移动设备上得到很好的应用。Adobe为移动优化过的皮肤在设计时就考虑到平衡两个对立的目标:性能优异却又容易创建。虽然MXML皮肤在某些情况下是有用的,但Adobe还是建议遵循以下简单的方针,确保Flex 4.5移动应用程序能够同时满足开发者和最终用户的性能要求。
这是介绍Flex 4.5移动皮肤特性系列文章中的第一篇。
本文将涵盖创建移动增强皮肤的基本知识,包括:
Spark主题和Mobile主题的区别
MobileSkin基类中包含的性能优化
用FXG替代MXML图形
基于Mobile主题的ButtonSkin类创建自定义的Button皮肤
该系列文章中的余下几篇将会介绍更多高级主题,包括:
基于MobileSkin基类构建新的皮肤
创建空间感知的皮肤,可以适应所有屏幕尺寸
使用CSS媒体查询为每个平台创建自定义的主题
Mobile主题基本是Flex 4引入的Spark主题功能集的一个子集。Mobile主题专门针对性能和内存占用问题进行的优化。
Spark 皮肤通常需要继承 Skin (它扩展了 Group) 或者 SparkSkin (它扩展了 Skin)。Mobile主题里的皮肤使用一个新的基类MobileSkin,它扩展了UIComponent。
MobileSkin对状态的支持是它一项针对移动开发优化过的主要特性。一般情况下,使用状态特性(在MXML或者ActionScript)都会带来额外的内存和性能消耗。而MobileSkin不再用State类及子类,而是手工的在代码里处理状态改变,例如
因为MobileSkin不是一个 Group, 它不能使用 Spark的基于约束的布局。例如 HorizontalLayout, VerticalLayout和BasicLayout 。
MobileSkin的内容在代码中人工的布局。MobileSkin加入了新的生命周期方法
Mobile主题中皮肤的图形由编译过的FXG和用于绘制的ActionScript代码构成。绘制代码仅用于琐碎的图形或者需要支持样式的时候。处于性能优化的考虑,所有其他图形都使用编译过的FXG。MobileSkin基类不选择使用MXML图形,除非他们都包含在一个Group当中。
Mobile主题在默认皮肤中不会使用Flash Text Engine (FTE)或者Text Layout Framework (TLF) 。这主要是基于性能的考虑,并且为了支持原生的文本输入和编辑。
Flex 4.5在mobilecomponents.swc中引入了一个新的StyleableTextField类。它扩展了TextField,并且加入了对样式的支持。它专门用于那些不准备与MXML结合使用的移动ActionScript皮肤和渲染器。
在同时使用StyleableTextField 和 Label (基于 FTE)时,开发者必须嵌入字体两次。Label 使用
TextField 和 StyleableTextField 用
Adobe不建议在移动项目中使用RichEditableText组件。请用TextArea组件代替。
由于MobileSkin删除了MXML皮肤的需要主要的申明性特性(状态、布局和MXML图形),Adobe建议用ActionScript编写皮肤。没有这三个特性,用MXML做声明性的标识已经没有什么优势了。
注意: 在Flash Builder中,可以指定库和主题的SWCs的代码或者编译过的ActionScript皮肤,由设计视同渲染出MXML皮肤。但设计视图不能通过指定代码渲染ActionScript皮肤。
由于上文提到限制,Mobile主题删除了一些样式,包括:
不支持,因为基础可触屏的界面是目前主要环境。
不支持,因为这些参数是编译过的FXG的属性,他们不会在运行时发生变化
不支持,为性能考虑,尽量减少过滤器的使用。
Flash Builder 会根据当前选择的主题,在MXML和CSS编辑器中正确的显示或者隐藏样式属性
由于各种原因,某些Spark组件在Mobile主题中没有皮肤。例如,有些组件在Mobile UI下没有什么作用,或者它根本就不是 Flex 4.5 版本的主要目标,可能在下一个发行版中专门为移动平台进行优化。这些组件包括:
ComboBox and DropDownList
NumericStepper
ToggleButton
VideoDisplay and VideoPlayer
VSlider
Panel
TabBar (the component used in TabbedViewNavigator is actually a ButtonBar)
TitleWindow
开始使用皮肤特性的最佳方式是,基于默认的Buton皮肤,创建一个自定义的Button皮肤。为了让问题简单化,这个例子没有考虑到屏幕DPI的问题。笔者将在系列文章的其他篇幅讨论这些问题。
首先,使用 Adobe Illustrator CS5为Button图形创建一个FXG文件。这个文件将同时展现Button组件的
其次,通过重载MobileSkin的
根据自己的喜好,可以选择Adobe Flash Professional、Adobe Illustrator或者 Adobe Fireworks构建FXG。你也可以在Flash Builder中手工编辑FXG,然后在MXML文件中移动这个FXG,再用设计视图渲染它,可视化的检查结果。
这个例子用 Illustrator 创建一个药丸形状的Button图形.
在Illustrator中,选择 File > New。
为图形命名,例如RoundedButtonExport。
设置 New Document Profile 为Flash Catalyst。
设置大小为典型的手机尺寸 480 px x 800 px 。
点击 OK
用矩形工具新建一个由灰色笔触,渐变填充的矩形。
在Stroke面板中,找到Align Stroke,选择中间的Align Stroke To Inside选项。默认情况下,笔触都是居中对齐的。笔者将稍候介绍为什么最好避免使用这个默认值。
修改 X 和 Y 位置为 0.
选中矩形后,选择 Effect > Stylize > Round Corners。
指定角的半径为 22 px。
保存为没有私有数据的 FXG 。
导出FXG文件后,你可能希望清理一些不需要的标签,例如多余的Group标签或者私有的命名空间数据。这个步骤不是必须的,不过这样做可以让你的FXG更容易让人理解。
RoundedButtonExport.fxg
RoundedButtonCleanup.fxg
测试 FXG
导出和清理 FXG之后,你可以把它丢进一个MXML文件中,用设计视图预览,从而快速的验证它是否工作。
尝试以下步骤:
在Flash Builder中新建一个项目(可以命名为任何名字)。
在源代码文件夹中加入 FXG 文件。
切换到设计视图
组件面板将会把FXG文件显示为一个自定义组件。
拖拽这个组件到设计区域。你可以看到FXG被渲染成原本的大小。
在设计视图中,尝试改变FXG的宽度。
你将发现圆角在水平方向拉伸(见图1)。但你希望看到的应该是圆角的形状保持不变,而是让图形的中间部分拉伸。为此,需要为FXG加入伸缩网格信息。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig01.jpg)
图 1.缺少伸缩网格数据
为让grid伸缩适当的伸缩,你需要添加网格的左、右、上和下的位置信息。因为使用了Round Corners风格化选项,我们知道当前的半径是22px。有了这些信息,你可以打开Flash Builder,对FXG文件做如下修改:
在
220px)
你还需要确保边界的笔锋没有伸缩。
在同一个标签中,为这个图形添加
44px)
注意: 对于有些图形,很难找到任意路径上的精确起始点。这种情况下,请使用Illustrator的选择工具去覆盖一个锚点,从而找到它的坐标(见图2)。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig02.jpg)
图 2.找到锚点坐标
在Graphic根标签添加网格数据之后,查看一下设计视图中的新FXG,你会发现没有什么变化。因为路径信息并没有填满图形的全部尺寸,所以伸缩网格没有变化。
为了修复这个问题,如下所示,添加一个透明的Rect占据整个图形空间。
将刚做的修改保存为RoundedButton.fxg.
RoundedButton.fxg
现在,设计视图中的Button应该伸缩自如了。(见图 3)
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig03.jpg)
图 3.添加了伸缩网格后的组件。
基于现有的Mobile主题,创建一个新的Button皮肤的过程氛围3个主要步骤。
新建一个spark.skins.mobile.ButtonSkin的子类。
在构造函数中,设置FXG类的
用CSS或者XML设置Button的
注意: 这个项目的示例文件中包含RoundedButtonSkinProject.fxp。您可以将这个文件导入Flash Builder,查看完整的应用程序(包括皮肤在内)是如何实现的。
关于
不支持
重载
绘制
– 重载
为
- 重载
这个例子演示了第三种方法。
下面的代码是皮肤的最终实现。
RoundedButtonSkin.as
教程步骤3: 测试
下面的代码将定制过的RoundedButtonSkin设置为Button的默认皮肤。为了演示
在应用程序中添加一些Button后,你应该能看到他们的新皮肤在弹起和按下时的不同状态(见图4)。down状态时的皮肤表明CSS样式已经起作用了。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig04.jpg)
图 4.拥有新皮肤的Button。
在处理FXG时,请记住下列注意事项。
路径信息并不总是很容易找到,但有些情况下,路径还可能与一些反锯齿的元素渲染在一起。你每次需要获得的路径信息总是不同的。当你在Illustrator中难以获取路径信息时,不要立刻就期望简化原始图形。
图形元素的
Player或者AIR运行时将会正确的判断出元素本身是否需要根据
通常情况下,笔触会横跨图形的边缘(例如,在Illustrator中使用"笔触居中对其")
举例来说,画一条从(0,0)到(0,100)的一条线,它有1个像素宽的笔触。该笔触将会从X轴的-.5延展到.5。但是由于在小数位的像素空间内无法绘制任何东西,Flash将会画一条反锯齿的2个像素宽的线,正好占据该小数宽度位置。为了消除反锯齿的干扰,画图形的时候使用奇数做为笔触大小,使得它能有半个像素的边界。例如,一个占据(10,10)位置的、
尽可能使用填充矩形,而非有笔触的矩形和线条。如果必须使用有笔触的
在用FXG设计图形时,必须考虑到伸缩网格的一些局限。
伸缩网格的值必须在图形的边界之内,并且不能与特性边界重合(也就是说,左边界
右边界)。
如果图形包含Group元素,就不能用伸缩网格。
如果元素使用了
FXG的完整规范,请参考《FXG 2.0 - 功能与设计规范》
这是介绍Flex 4.5移动皮肤特性系列文章中的第一篇。
本文将涵盖创建移动增强皮肤的基本知识,包括:
Spark主题和Mobile主题的区别
MobileSkin基类中包含的性能优化
用FXG替代MXML图形
基于Mobile主题的ButtonSkin类创建自定义的Button皮肤
该系列文章中的余下几篇将会介绍更多高级主题,包括:
基于MobileSkin基类构建新的皮肤
创建空间感知的皮肤,可以适应所有屏幕尺寸
使用CSS媒体查询为每个平台创建自定义的主题
比较Spark和Mobile 主题
Mobile主题基本是Flex 4引入的Spark主题功能集的一个子集。Mobile主题专门针对性能和内存占用问题进行的优化。
MobileSkin 基类
Spark 皮肤通常需要继承 Skin (它扩展了 Group) 或者 SparkSkin (它扩展了 Skin)。Mobile主题里的皮肤使用一个新的基类MobileSkin,它扩展了UIComponent。
状态
MobileSkin对状态的支持是它一项针对移动开发优化过的主要特性。一般情况下,使用状态特性(在MXML或者ActionScript)都会带来额外的内存和性能消耗。而MobileSkin不再用State类及子类,而是手工的在代码里处理状态改变,例如SetProperty和
AddChild。
布局
因为MobileSkin不是一个 Group, 它不能使用 Spark的基于约束的布局。例如 HorizontalLayout, VerticalLayout和BasicLayout 。MobileSkin的内容在代码中人工的布局。MobileSkin加入了新的生命周期方法
layoutContents(),,它在
updateDisplayList()中被调用。这个方法用于放置皮肤的子元素。
FXG 和 MXML 图形
Mobile主题中皮肤的图形由编译过的FXG和用于绘制的ActionScript代码构成。绘制代码仅用于琐碎的图形或者需要支持样式的时候。处于性能优化的考虑,所有其他图形都使用编译过的FXG。MobileSkin基类不选择使用MXML图形,除非他们都包含在一个Group当中。
文本
Mobile主题在默认皮肤中不会使用Flash Text Engine (FTE)或者Text Layout Framework (TLF) 。这主要是基于性能的考虑,并且为了支持原生的文本输入和编辑。Flex 4.5在mobilecomponents.swc中引入了一个新的StyleableTextField类。它扩展了TextField,并且加入了对样式的支持。它专门用于那些不准备与MXML结合使用的移动ActionScript皮肤和渲染器。
在同时使用StyleableTextField 和 Label (基于 FTE)时,开发者必须嵌入字体两次。Label 使用
embedAsCFF=true,而
TextField 和 StyleableTextField 用
embedAsCFF=false。
Adobe不建议在移动项目中使用RichEditableText组件。请用TextArea组件代替。
MXML 和 ActionScript
由于MobileSkin删除了MXML皮肤的需要主要的申明性特性(状态、布局和MXML图形),Adobe建议用ActionScript编写皮肤。没有这三个特性,用MXML做声明性的标识已经没有什么优势了。注意: 在Flash Builder中,可以指定库和主题的SWCs的代码或者编译过的ActionScript皮肤,由设计视同渲染出MXML皮肤。但设计视图不能通过指定代码渲染ActionScript皮肤。
不支持的全局样式
由于上文提到限制,Mobile主题删除了一些样式,包括:rollOverColor–
不支持,因为基础可触屏的界面是目前主要环境。
borderAlpha,
borderColor,
cornerRadius–
不支持,因为这些参数是编译过的FXG的属性,他们不会在运行时发生变化
dropShadowVisible–
不支持,为性能考虑,尽量减少过滤器的使用。
Flash Builder 会根据当前选择的主题,在MXML和CSS编辑器中正确的显示或者隐藏样式属性
Mobile中避免使用的组件
由于各种原因,某些Spark组件在Mobile主题中没有皮肤。例如,有些组件在Mobile UI下没有什么作用,或者它根本就不是 Flex 4.5 版本的主要目标,可能在下一个发行版中专门为移动平台进行优化。这些组件包括:ComboBox and DropDownList
NumericStepper
ToggleButton
VideoDisplay and VideoPlayer
VSlider
Panel
TabBar (the component used in TabbedViewNavigator is actually a ButtonBar)
TitleWindow
Button皮肤教程概述
开始使用皮肤特性的最佳方式是,基于默认的Buton皮肤,创建一个自定义的Button皮肤。为了让问题简单化,这个例子没有考虑到屏幕DPI的问题。笔者将在系列文章的其他篇幅讨论这些问题。首先,使用 Adobe Illustrator CS5为Button图形创建一个FXG文件。这个文件将同时展现Button组件的
up和
down皮肤状态。因为这里主要针对触摸输入,所以没有创建
over状态。
其次,通过重载MobileSkin的
drawBackground()方法,添加对
chromeColor样式的支持。或者,也可以手动在up和down的图形里添加固定的背景颜色,然后重载
drawBackground()方法,不作任何事情。
disabled状态仅仅会改变
up状态的
alpha值。移动ButtonSkin类已经默认包含这个功能。
教程第一步:创建FXG图形
根据自己的喜好,可以选择Adobe Flash Professional、Adobe Illustrator或者 Adobe Fireworks构建FXG。你也可以在Flash Builder中手工编辑FXG,然后在MXML文件中移动这个FXG,再用设计视图渲染它,可视化的检查结果。
用 Illustrator 创建 FXG
这个例子用 Illustrator 创建一个药丸形状的Button图形.在Illustrator中,选择 File > New。
为图形命名,例如RoundedButtonExport。
设置 New Document Profile 为Flash Catalyst。
设置大小为典型的手机尺寸 480 px x 800 px 。
点击 OK
用矩形工具新建一个由灰色笔触,渐变填充的矩形。
在Stroke面板中,找到Align Stroke,选择中间的Align Stroke To Inside选项。默认情况下,笔触都是居中对齐的。笔者将稍候介绍为什么最好避免使用这个默认值。
修改 X 和 Y 位置为 0.
选中矩形后,选择 Effect > Stylize > Round Corners。
指定角的半径为 22 px。
保存为没有私有数据的 FXG 。
清理 FXG
导出FXG文件后,你可能希望清理一些不需要的标签,例如多余的Group标签或者私有的命名空间数据。这个步骤不是必须的,不过这样做可以让你的FXG更容易让人理解。RoundedButtonExport.fxg
<?xml version="1.0" encoding="utf-8" ?> <Graphic version="2.0" viewHeight="800" viewWidth="480" ai:appVersion="15.0.2.399" ATE:version="1.0.0" flm:version="1.0.0" d:using="" xmlns="http://ns.adobe.com/fxg/2008" xmlns:ATE="http://ns.adobe.com/ate/2009" xmlns:ai="http://ns.adobe.com/ai/2009" xmlns:d="http://ns.adobe.com/fxg/2008/dt" xmlns:flm="http://ns.adobe.com/flame/2008"> <Library/> <Group ai:seqID="1" d:layerType="page" d:pageHeight="800" d:pageWidth="480" d:type="layer" d:userLabel="Artboard 1"> <Group ai:seqID="2" d:type="layer" d:userLabel="Layer 1"> <Group ai:seqID="3" flm:knockout="false" d:type="layer" d:userLabel="RoundedButton"> <Group ai:seqID="4" flm:knockout="false"> <Path x="0.5" y="1" winding="nonZero" ai:seqID="5" data="M21.5 43C9.64502 43 0 33.355 0 21.5 0 9.64502 9.64502 0 21.5 0L197.5 0C209.355 0 219 9.64502 219 21.5 219 33.355 209.355 43 197.5 43L21.5 43Z"> <fill> <LinearGradient x="109.5" y="0" scaleX="43" rotation="90"> <GradientEntry ratio="0" color="#F0F0F0"/> <GradientEntry ratio="0.478788" color="#C8C8C8"/> <GradientEntry ratio="0.50303" color="#BBBBBB"/> <GradientEntry ratio="1" color="#F0F0F0"/> </LinearGradient> </fill> </Path> <Path winding="nonZero" ai:seqID="6" data="M198 1C209.58 1 219 10.4204 219 22 219 33.5796 209.58 43 198 43L22 43C10.4204 43 1 33.5796 1 22 1 10.4204 10.4204 1 22 1L198 1M198 0 22 0C9.8999 0 0 9.8999 0 22 0 34.1001 9.8999 44 22 44L198 44C210.1 44 220 34.1001 220 22 220 9.8999 210.1 0 198 0L198 0Z"> <fill> <SolidColor color="#DDDDDD"/> </fill> </Path> </Group> </Group> </Group> </Group> <Private/> </Graphic>
RoundedButtonCleanup.fxg
<?xml version="1.0" encoding="utf-8" ?> <Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008"> <Path x="0.5" y="1" winding="nonZero" data="M21.5 43C9.64502 43 0 33.355 0 21.5 0 9.64502 9.64502 0 21.5 0L197.5 0C209.355 0 219 9.64502 219 21.5 219 33.355 209.355 43 197.5 43L21.5 43Z"> <fill> <LinearGradient x="109.5" y="0" scaleX="43" rotation="90"> <GradientEntry ratio="0" color="#F0F0F0"/> <GradientEntry ratio="0.478788" color="#C8C8C8"/> <GradientEntry ratio="0.50303" color="#BBBBBB"/> <GradientEntry ratio="1" color="#F0F0F0"/> </LinearGradient> </fill> </Path> <Path winding="nonZero" data="M198 1C209.58 1 219 10.4204 219 22 219 33.5796 209.58 43 198 43L22 43C10.4204 43 1 33.5796 1 22 1 10.4204 10.4204 1 22 1L198 1M198 0 22 0C9.8999 0 0 9.8999 0 22 0 34.1001 9.8999 44 22 44L198 44C210.1 44 220 34.1001 220 22 220 9.8999 210.1 0 198 0L198 0Z"> <fill> <SolidColor color="#DDDDDD"/> </fill> </Path> </Graphic>
测试 FXG
导出和清理 FXG之后,你可以把它丢进一个MXML文件中,用设计视图预览,从而快速的验证它是否工作。
尝试以下步骤:
在Flash Builder中新建一个项目(可以命名为任何名字)。
在源代码文件夹中加入 FXG 文件。
切换到设计视图
组件面板将会把FXG文件显示为一个自定义组件。
拖拽这个组件到设计区域。你可以看到FXG被渲染成原本的大小。
在设计视图中,尝试改变FXG的宽度。
你将发现圆角在水平方向拉伸(见图1)。但你希望看到的应该是圆角的形状保持不变,而是让图形的中间部分拉伸。为此,需要为FXG加入伸缩网格信息。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig01.jpg)
图 1.缺少伸缩网格数据
手工添加scale grids
为让grid伸缩适当的伸缩,你需要添加网格的左、右、上和下的位置信息。因为使用了Round Corners风格化选项,我们知道当前的半径是22px。有了这些信息,你可以打开Flash Builder,对FXG文件做如下修改:在
<Graphic>根标签中添加
scaleGridLeft="22"和
scaleGridRight="198px"(图形的完整宽度是
220px)
你还需要确保边界的笔锋没有伸缩。
在同一个标签中,为这个图形添加
scaleGridTop="1px"和
scaleGridBottom="43px"(图形的完整高度是
44px)
注意: 对于有些图形,很难找到任意路径上的精确起始点。这种情况下,请使用Illustrator的选择工具去覆盖一个锚点,从而找到它的坐标(见图2)。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig02.jpg)
图 2.找到锚点坐标
在Graphic根标签添加网格数据之后,查看一下设计视图中的新FXG,你会发现没有什么变化。因为路径信息并没有填满图形的全部尺寸,所以伸缩网格没有变化。
为了修复这个问题,如下所示,添加一个透明的Rect占据整个图形空间。
将刚做的修改保存为RoundedButton.fxg.
RoundedButton.fxg
<?xml version="1.0" encoding="utf-8" ?> <Graphic version="2.0" xmlns="http://ns.adobe.com/fxg/2008" scaleGridLeft="22" scaleGridRight="198" scaleGridTop=”1” scaleGridBottom=”43”> <Path x="0.5" y="1" winding="nonZero" data="M21.5 43C9.64502 43 0 33.355 0 21.5 0 9.64502 9.64502 0 21.5 0L197.5 0C209.355 0 219 9.64502 219 21.5 219 33.355 209.355 43 197.5 43L21.5 43Z"> <fill> <LinearGradient x="109.5" y="0" scaleX="43" rotation="90"> <GradientEntry ratio="0" color="#F0F0F0"/> <GradientEntry ratio="0.478788" color="#C8C8C8"/> <GradientEntry ratio="0.50303" color="#BBBBBB"/> <GradientEntry ratio="1" color="#F0F0F0"/> </LinearGradient> </fill> </Path> <Path winding="nonZero" data="M198 1C209.58 1 219 10.4204 219 22 219 33.5796 209.58 43 198 43L22 43C10.4204 43 1 33.5796 1 22 1 10.4204 10.4204 1 22 1L198 1M198 0 22 0C9.8999 0 0 9.8999 0 22 0 34.1001 9.8999 44 22 44L198 44C210.1 44 220 34.1001 220 22 220 9.8999 210.1 0 198 0L198 0Z"> <fill> <SolidColor color="#DDDDDD"/> </fill> </Path> <!-- scale grid fix --> <Rect x="0" y="0" width="220" height="44"> <fill> <SolidColor color="#000000" alpha="0"/> </fill> </Rect> </Graphic>
现在,设计视图中的Button应该伸缩自如了。(见图 3)
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig03.jpg)
图 3.添加了伸缩网格后的组件。
教程步骤2: 创建皮肤类
基于现有的Mobile主题,创建一个新的Button皮肤的过程氛围3个主要步骤。新建一个spark.skins.mobile.ButtonSkin的子类。
在构造函数中,设置FXG类的
upBorderSkin和
downBorderSkin属性。注意,这些是类实行,而不是FXG的实例。同样,为FXG的尺寸信息设置
measuredDefaultHeight和
measuredDefaultWidth属性(参考下面的代码片段)。
用CSS或者XML设置Button的
skinClass属性。
注意: 这个项目的示例文件中包含RoundedButtonSkinProject.fxp。您可以将这个文件导入Flash Builder,查看完整的应用程序(包括皮肤在内)是如何实现的。
关于
chromeColor样式,你有3个选择:
不支持
chromeColor–
重载
drawBackground(),不作任何事情
绘制
chromeColor,使其符合FXG图形
– 重载
drawBackground(),用代码绘制
chromeColor。并且为FXG添加alpha值,使得
chromeColor可见。
为
chromeColor填色
- 重载
drawBackground(),用工具方法
applyColorTransform()将FXG从基色转变为特定的
chromeColor。
这个例子演示了第三种方法。
下面的代码是皮肤的最终实现。
RoundedButtonSkin.as
package skins { import skins.assets.RoundedButton; import spark.skins.mobile.ButtonSkin; public class RoundedButtonSkin extends ButtonSkin { private var colorized:Boolean = false; public function RoundedButtonSkin() { super(); // replace FXG asset classes upBorderSkin = skins.assets.RoundedButton; downBorderSkin = skins.assets.RoundedButton; measuredDefaultHeight = 44; measuredDefaultWidth = 220; } override protected function drawBackground(unscaledWidth:Number, unscaledHeight:Number):void { // omit call to super.drawBackground() to apply tint instead and don't draw fill var chromeColor:uint = getStyle("chromeColor"); if (colorized || (chromeColor != 0xDDDDDD)) { // apply tint instead of fill applyColorTransform(border, 0xDDDDDD, chromeColor); // if we restore to original color, unset colorized colorized = (chromeColor != 0xDDDDDD); } } } }
教程步骤3: 测试
下面的代码将定制过的RoundedButtonSkin设置为Button的默认皮肤。为了演示
chromeColor和CSS,作者在此为Buttondown状态加入了一些样式。
<fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; s|Button { skinClass: ClassReference("skins.RoundedButtonSkin"); } s|Button:down { chromeColor: #0000FF; color: #FFFFFF; textShadowColor: #000000; } </fx:Style>
在应用程序中添加一些Button后,你应该能看到他们的新皮肤在弹起和按下时的不同状态(见图4)。down状态时的皮肤表明CSS样式已经起作用了。
![](http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/flex/articles/mobile-skinning-part1/fig04.jpg)
图 4.拥有新皮肤的Button。
FXG 提示与技巧
在处理FXG时,请记住下列注意事项。
路径 vs 原始图形
路径信息并不总是很容易找到,但有些情况下,路径还可能与一些反锯齿的元素渲染在一起。你每次需要获得的路径信息总是不同的。当你在Illustrator中难以获取路径信息时,不要立刻就期望简化原始图形。
blendMode
图形元素的blendMode属性默认是设置为
自动的。当它是
auto时候,Flash
Player或者AIR运行时将会正确的判断出元素本身是否需要根据
alpha值使用
blendMode层。
尽可能避免笔触
通常情况下,笔触会横跨图形的边缘(例如,在Illustrator中使用"笔触居中对其")举例来说,画一条从(0,0)到(0,100)的一条线,它有1个像素宽的笔触。该笔触将会从X轴的-.5延展到.5。但是由于在小数位的像素空间内无法绘制任何东西,Flash将会画一条反锯齿的2个像素宽的线,正好占据该小数宽度位置。为了消除反锯齿的干扰,画图形的时候使用奇数做为笔触大小,使得它能有半个像素的边界。例如,一个占据(10,10)位置的、
1个像素宽的
SolidColorStroke笔触,应该实际占位在(10.5,10.5)。
尽可能使用填充矩形,而非有笔触的矩形和线条。如果必须使用有笔触的
填充
矩形,那可以尝试把它分位两个填充矩形(假设填充万全不透明)。如果要画一个条线,尝试把它转变为一个填充矩形。例如,如果要画一条水平直线,可以创建一个高度等同于线条笔触的填充矩形。
伸缩网格
在用FXG设计图形时,必须考虑到伸缩网格的一些局限。伸缩网格的值必须在图形的边界之内,并且不能与特性边界重合(也就是说,左边界
scaleGridLeft<
scaleGridRight<
右边界)。
如果图形包含Group元素,就不能用伸缩网格。
如果元素使用了
alpha属性,伸缩网格也不能使用。所以,只在笔触和
填充元素上应用
alpha。
FXG规范
FXG的完整规范,请参考《FXG 2.0 - 功能与设计规范》
相关文章推荐
- 将Flex 3应用程序移植到Flex 4.5中 第3部分:Spark组件及皮肤制作简介 (一)
- 第一部分:基础知识(第一章)标准的Silverlight文件(续)
- Flex移动皮肤开发(三)
- 第一部分:基础知识(第一章)XAP 就是 ZIP
- 【转】深入浅出Flex组件生命周期Part2 ─ 使用ActionScript3开发移动Spark组件的皮肤类
- 部署Windows 7-第1部分:Windows AIK 2.0增强功能
- 《陇原商城》实训报告之第一部分 系统功能的描述 希望各位提点意见,以供我在增加功能
- 第一部分:开发前的准备-第二章 基础入门
- 《C++捷径教程》读书笔记--Chapter 7--函数,第一部分:基础知识(第一部分)
- 3D编程指南第一部分:快速进入移动JAVA 3D编程世界
- 第一部分:基础知识(第一章)屏幕部分续
- C#基础系列(1)-- 第一部分 基础数据类型与操作 -- 位运算(1)
- 移动Web开发基础-百分比+flex布局方案
- C++Primier笔记第一部分 基础
- 将Flex 3应用程序移植到Flex 4.5中 第3部分:Spark组件及皮肤制作简介 (二)
- More Effective C++ 第一部分 基础议题
- 第一部分:基础知识(第一章)XAP 就是 ZIP
- jBPM4工作流开发实战 之 第一部分 工作流基础
- 《C++捷径教程》读书笔记--Chapter 7--函数,第一部分:基础知识(第二部分)
- OC基础-零基础学习Objective-C:第一部分.类和对象