英文原文: http://www.adobe.com/devnet/flex/articles/flex4_skinning.html
本文翻译原创链接: http://www.smithfox.com/?e=34
转载请注明
翻译: smithfox
上接:
http://smithfox.iteye.com/admin/blogs/847465
制作slider皮肤
皮肤parts不仅可以推送组件数据到皮肤中,组件也可以用它们来注册行为。为了讲得更明白,以slider组件为例。slider两个主要
parts是轨迹条和滑动块。在这个例子中,该组件没有把任何数据推送到皮肤来显示,但它添加了事件监听器到parts中并且会根据组件的value属性
执行滑动块的布局。例如,当点击轨迹条,组件会更新其value属性并且定位滑动块到适当位置。此外,还有动态皮肤parts,数据提示,这是用来拖动滑
块时显示弹出的提示信息。 在图6所示是一个简单slider和一个修改后的slider。
图6: 修改后的slider(左边) 和原来的slider (右边)
为构建这个, 你的皮肤文件必须声明三个皮肤parts: thumb(滑块), track(轨迹条), and dataTip(数据提示)。
MySliderSkin.mxml
01
|
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
|
04
|
minWidth
=
"11"
minHeight
=
"100"
alpha.disabled
=
"0.5"
>
|
06
|
[HostComponent("spark.components.VSlider")]
|
09
|
<
s:State
name
=
"normal"
/>
|
10
|
<
s:State
name
=
"disabled"
/>
|
14
|
<
fx:Component
id
=
"dataTip"
>
|
15
|
<
s:DataRenderer
minHeight
=
"24"
minWidth
=
"40"
x
=
"20"
>
|
16
|
<
s:Rect
top
=
"0"
left
=
"0"
right
=
"0"
bottom
=
"0"
>
|
18
|
<
s:SolidColor
color
=
"0xFFF46B"
alpha
=
".9"
/>
|
21
|
<
s:DropShadowFilter
angle
=
"90"
color
=
"0x999999"
distance
=
"3"
/>
|
25
|
<
s:Label
id
=
"labelField"
text
=
"{data}"
|
26
|
horizontalCenter
=
"0"
verticalCenter
=
"1"
|
27
|
left
=
"5"
right
=
"5"
top
=
"5"
bottom
=
"5"
|
28
|
textAlign
=
"center"
verticalAlign
=
"middle"
color
=
"0x555555"
/>
|
33
|
<
s:Button
id
=
"track"
left
=
"5"
right
=
"5"
top
=
"0"
bottom
=
"0"
skinClass
=
"MyTrackSkin"
/>
|
34
|
<
s:Button
id
=
"thumb"
left
=
"0"
right
=
"0"
width
=
"18"
height
=
"8"
skinClass
=
"MyThumbSkin"
/>
|
在皮肤中定义了这些皮肤parts这后,组件负责处理他们。它添加事件监听器到滑块,让你可以在轨迹条中拖动滑块。
它还根据相应的value值来定位滑块。请看一下上面示例代码中的MyTrackSkin和MyThumbSkin。你会看到许多FXG的例子。请注意,
自定义的滑块皮肤相比默认Spark滑块皮肤有着完全不同的形状。
"数据提示"皮肤part是动态的 -- 它负责生成和布局。当前的例子中,当你拖动滑块,会在滑块右边弹出数据提示。有了皮肤契约,皮肤可以只管定义皮肤part,和所有可视化方面的内容,而不必担心有什么副作用。 所有的衔接都由组件来处理。
注:一些Flex 4内置组件不仅附加行为到皮肤parts上,同时也会推送数据到皮肤parts。另一种得到皮肤中数据的方法是通过hostComponent属性来拉他们。
当一个组件创建了皮肤时,并非所有的皮肤parts是必需的。 例如,VSlider的数据提示皮肤part并不是必需的。 如果它不存在,就不显示数据提示。
创建可变换皮肤组件
Spark可变换皮肤组件没有在幕后做什么特别的事情。. They have data properties and advertise
the skin parts and skin states they need through metadata。
他们还有少许关键的方法来用管理皮肤和皮肤parts的生命周期。您也可以和它一样轻松地创建一个新的换肤组件。
为了演示一下,你可以创建一个简单NoteCard组件,它可以用来在屏幕上显示笔记。在图7所示的例子中,应用程序随机创建多个语录。
图7: NoteCard 组件例子
主应用程序仅创建一个有点旋转的语录NoteCard。 有趣的部分是NoteCard类,它扩展了spark.components.supportClasses.SkinnableComponent类并且在生命周期方法中添加代码。
NoteCard.as:
04
|
[SkinState(
"normal"
)]
|
05
|
[SkinState(
"disabled"
)]
|
06
|
public
class
NoteCard
extends
SkinnableComponent
|
08
|
public
function
NoteCard()
|
13
|
[SkinPart(required=
"true"
)]
|
14
|
public
var
labelDisplay:TextBase;
|
16
|
[SkinPart(required=
"false"
)]
|
17
|
public
var
closeButton:Button;
|
19
|
private
var
_text:
String
;
|
21
|
public
function
get
text():
String
|
26
|
public
function
set
text(value:
String
):
void
|
此组件声明数据属性,皮肤states,皮肤parts。 对于数据,NoteCard有一个公共的text属性。
此外,NoteCard有两个皮肤states,normal和disabled,用SkinStates元数据声明在类声明代码的上面。
这就告诉皮肤,它需要实现这两个states。
NoteCard还有两个皮肤parts,是通过SkinPart元数据声明的。
SkinPart元数就直接声明在皮肤part名称之上。
当前例子,labelDisplay是必需的TextBase类皮肤part,closeButton是一个可选的Button类皮肤part。
由于皮肤是运行时载入,当组件第一次启动时,你不能保证有一定有皮肤。 你也不能保证已经有了全部的皮肤parts,尤其是他们是可选的。 框架负责了这些事情: 衔接part声明和组件属性定义,并且通过皮肤生命周期方法通知组件parts已经准备好了。
实现皮肤states
为实现皮肤states,你需重写getCurrentSkinState()方法以返回皮肤当前所处状态,当前例子中,它会返回"normal"
或"disabled"。当一些事件导致皮肤state变得无效时,组件应该调用invalidateSkinState()方法。
NoteCard.as
03
|
[SkinState(
"normal"
)]
|
04
|
[SkinState(
"disabled"
)]
|
05
|
public
class
NoteCard
extends
SkinnableComponent
|
08
|
override
public
function
set
enabled(value:
Boolean
) :
void
|
11
|
invalidateSkinState();
|
12
|
super
.enabled = value;
|
15
|
override
protected
function
getCurrentSkinState() :
String
|
当设置enabled属性时,enabled setter调用invalidateSkinState()以通知皮肤,组件的state需要改变,这样getCurrentSkinState()随即会被调用。
处理皮肤parts
处理皮肤parts,有两种主要方法应该要重写,partAdded()和partRemoved()。这些方法会告诉你一个特定的皮肤part被
添加了或被删除了。当装载一个皮肤时Parts将被加入或是删除。皮肤是在运行时交换的,并且延迟加载的,所以只有在某种states情况下或者是一个动
态part刚刚被创建时part才会被加入。在partAdded()方法你可以设置你想要的任何数据到part,而且也可以attach一些事件侦听到
part上。当part被删除时,你应该在partRemoved()方法中做相反的事情。
NoteCard.as
03
|
public
class
NoteCard
extends
SkinnableComponent
|
05
|
[SkinPart(required=
"true"
)]
|
06
|
public
var
labelDisplay:TextBase;
|
08
|
[SkinPart(required=
"false"
)]
|
09
|
public
var
closeButton:Button;
|
11
|
public
function
set
text(value:
String
):
void
|
18
|
labelDisplay.text = value;
|
21
|
override
protected
function
partAdded(partName:
String
, instance:
Object
) :
void
|
23
|
super
.partAdded(partName, instance);
|
25
|
if
(instance == labelDisplay)
|
26
|
labelDisplay.text = _text;
|
27
|
if
(instance == closeButton)
|
28
|
closeButton.addEventListener(MouseEvent.CLICK, closeButton_clickHandler);
|
31
|
override
protected
function
partRemoved(partName:
String
, instance:
Object
) :
void
|
33
|
super
.partRemoved(partName, instance);
|
35
|
if
(instance == closeButton)
|
36
|
closeButton.removeEventListener(MouseEvent.CLICK, closeButton_clickHandler);
|
39
|
protected
function
closeButton_clickHandler(event:MouseEvent) :
void
|
41
|
event.stopPropagation();
|
43
|
IVisualElementContainer(parent).removeElement(
this
);
|
在partAdded()方法中,当labelDisplay
part加入时,我设置text到这个part。此外,在text属性的setter方法中,我检查,看看是否已经加入labelDisplay,如果是
的话,我重新设置labelDisplay.text为组件的_text值以保证和组件text属性同步。在partAdded()方法中,我添加一个
click事件监听器到closeButton皮肤part。在partRemoved()我一定要删除这个click事件监听器。
作为一个
SkinnableComponent ,你需要做的就是利用这个强大的换肤机制。
当有人创造了某个组件的皮肤,他们必须实现皮肤states和皮肤parts以得到期望的组件行为。
在图6所示的皮肤在样例源代码中可以找到,即使这是一个简单的组件定义,你依然可以用不同的皮肤完全改变它的外观和体验。这就是皮肤真正的力量。
注:
当创建可变换皮肤组件,您可能要决定某些行为是属于皮肤的还是组件。 没有一个明确的硬性的规则。只要能让你的工作更容易就行了。
作为一般指导,一切外观和感观的定义应在皮肤MXML文件中声明。
另一方面,如果有多个皮肤想要某个特殊行为,那么将这个行为放在组件可能是一个好主意。例如,slider中滑块的定位是做在VSlider和
HSlider,没有在皮肤上。
下一步到哪里
Flex 4皮肤发生了重大修改。
明确分开了组件和皮肤。该组件包含了数据,行为和核心逻辑,而皮肤定义了组件的外观和体验。组件由ActionScript编写而皮肤写在MXML中,这
是托FXG和新states语法的福。 组件和皮肤通过皮肤契约进行交互。
又因为它们是各自独立的文件,所以新的皮肤很容易应用到组件上从而完全改变他们的外观。
欲了解更多的Flex 4皮肤信息,请查看 皮肤架构规范 以及 Gumbo组件架构白皮书。
分享到:
相关推荐
flex-messaging-core-4.7.3.jar 最新版,下载了好长时间才下载下来,亲测可用!
在Flex 4中,皮肤(Skin)是一种强大的机制,用于改变和定制UI组件的外观和交互体验。本文将深入探讨FLEX4中的皮肤系统,特别是SparkSkin类,并通过实例展示如何创建和应用自定义皮肤。 1. SparkSkin的介绍: ...
非常好DEMO参考,这个项目已经转到Apache名下了,最新的版本1.2,308个例子,已经全站打包,搜索:flex-tour-de-flex-component-explorer-1.2-308demo。开源代码http://flex.apache.org/download-tourdeflex.html
资源包含flex-2.5.4+bison-2.4.1+mingw,此外包含本人写的测试源码,编译命令及详细过程,另附一些有用的文章pdf,用于编译原理课程学习。详细使用参考文章:...
离线安装包,亲测可用
flex-messaging-core-amf1.7
非常好DEMO参考,这个项目已经转到Apache名下了,最新的版本1.2,308个例子,已经全站打包,搜索:flex-tour-de-flex-component-explorer-1.2-308demo。开源代码http://flex.apache.org/download-tourdeflex.html
下面将详细介绍如何在Flex4中自定义组件皮肤。 1. **组件皮肤的基本概念** - 组件皮肤是Flex中改变组件外观的一种方式,通过定义不同的皮肤,可以改变组件的颜色、形状、边框等视觉元素。 - Flex4引入了Spark组件...
FLEX开发工具。Flex Builder 4-7 win64 安装文件,第三卷。
Flex4 的皮肤系统是一个基于MXML和CSS的可扩展框架,允许开发者分离界面的视觉表现与功能逻辑。这套"flex4 皮肤"包含了解压后即可使用的皮肤主题,以及源代码,对于开发者来说,这是一个宝贵的资源,可以快速改变...
在这个“flex------组件-----数据可视化”主题中,我们将探讨Flex如何帮助开发者创建交互式的数据图表和可视化效果。 Flex框架提供了一套强大的组件库,其中包括用于数据可视化的类和库。这些组件使得开发人员能够...
FLEX开发工具。Flex Builder 4-7 win64 安装文件,第四卷。
- **DataGrid组件**:介绍DataGrid组件的功能和使用方法。 - **数据绑定**:展示如何将数据源与DataGrid进行绑定。 #### 20. Flex和Java通信之BlazeDS - **BlazeDS介绍**:BlazeDS是一种用于实现Flex和Java服务器...
让我们深入探讨Flex Messaging的核心概念、功能以及4.7.3版本可能带来的改进。 Flex Messaging主要由以下组件构成: 1. ** BlazeDS**:BlazeDS是Adobe官方提供的开源服务器端组件,它为Flex应用提供了与Java后端...
Flex4是Adobe公司开发的一款功能强大的RIA(富互联网应用)开发框架。它是Flex3的继任者,带来了巨大的改进和全新的特性。本文档《Flex4-in-a-day》专注于向开发者介绍Flex4的主要新特性,以帮助他们快速入门并理解...
flex-messaging-common-1.0.jar 资源共享,有需要其他jar包的可以在评论留言,看到后我会陆续上传。
在Spring Flex 1.5.0.M2中,核心组件`spring-flex-1.5.0.M2.jar`扮演了关键角色,它是Spring和Flex集成的核心库,提供了诸如消息代理、配置支持和Spring服务代理等功能。这个库使得Flex客户端可以轻松地调用Spring...
flex-messaging-opt-1.0.jar 资源共享,有需要其他jar包的可以在评论留言,看到后我会陆续上传。
flex 布局有六个属性可以设置在容器上:flex-direction、flex-wrap、flex-flow、justify-content、align-items、align-content。 1. flex-direction 属性决定主轴的方向(即项目的排列方向)。它可能有四个值:row...