http://bbs.airia.cn/FLEX/thread-8427-1-2.aspx

原来看了很多flex3的书,提到皮肤时举例子基本上都是用图片或swf内含的矢量图,来分别替换控件的upskin、downskin、overskin……等等。弄得我一直有一个错觉,好像皮肤就是这么回事,用图片替换。也就无法动态更改颜色大小等属性了。

到了想定义spark控件皮肤的时候,才猛然发现,一个skin样式也没有了,这该怎么替换图片啊?唯独有一个skinclass的属性。

经过摸索,原来是这么一回事啊:据官方文档的描述是,spark组件的出现大部分是为了围绕全面兼容“flash catalyst”的使用。spark组件就是跟mx平行的一套,功能既然都一样,那为什么要再写一套呢?这正是为了让spark组件能直接使用FC导出的皮肤文件!刚开始看网上的评论,一直说flex4的皮肤机制改进了,多好多好。然后给了个例子,发现完全是代码的。感觉靠想象力根本就写不出来嘛,哪有改进?具体的关于spark的skin是如何使用的,请看Flex SDK 4(Gumbo)更方便的自定义样式、自定义SparkSkin,别人说过的我就不多说了,里面很明白的说了,spark组件的skinclass是怎么用的。后来又看了一个非常棒的FC视频教程Flash Catalyst and Flex 4: Part 1,顿时明白了,sparkskin原来根本不是用手写的,是直接画出来生成的。。。。。。

看完那个视频教程,你就会明白spark皮肤制作原来是这么的简单!我之后就开始深入AI的矢量图绘画了,把原来图片格式的皮肤都画了一遍,导入FC,再导出就都变代码化皮肤了。因为是代码化的,导出文件变得非常的小,而且由于代码化的好处,属性完全就在你的掌控之中了,可以运行时任意修改皮肤颜色等外观,完全可以做自定义皮肤了。(另外小小提示一下:AI里有些效果,比如说径向的渐变在FC里不能被很好的导入,会发生外观差别,我的技巧是,把矢量栅格化了,变成位图,导入FC后,一样可以使用。即使无法完全代码化,也依然推荐这么制作皮肤,因为位图的话是可以半透明的,你还是可以动态更改皮肤的背景颜色,也可以动态设置位图的透明度,控制力 还是很大滴。导出的皮肤会混合代码图和位图,不用担心,这些FC都为你编写好啦)

以上是学会了如何制作代码化的sparkskin,我后来更进了一步,琢磨怎么把代码化的皮肤用在MX组件上(嘿嘿,很邪恶吧?这样以后只要想要的外观都可以直接画了,导入FC转换就行啦,没办法,FC制作皮肤太简单了!)说这个之前,还是请大家回到前面提到的那篇文章吧,弄清楚mxskin和sparkskin的关系了,下面的问题就明朗了。

先来看下sparkskin是在css里是怎么定义的

代码 复制 - 运行

s|Button {       skinClass: ClassReference("com.rianote.flex.skin.KButton"); } 


看着跟mx的定义是不是很像?那就对了。我们只需要这么改:

代码 复制 - 运行

mx|Button {       upSkin: ClassReference("com.rianote.flex.skin.KButton"); } 


这里只定义了upskin,跟用图片没什么区别的,然后你再分别定义downSkin、overskin……就可以了。这只解决了一半,关键是要修改那个com.rianote.flex.skin.KButton皮肤类文件,因为它是为spark生成的,我们修改一下,才能让mx也能用。打开文件代码如下:

代码 复制 - 运行

<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:ai="http://ns.adobe.com/ai/2009">  <fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>  <s:states>   <s:State name="up"/>   <s:State name="over"/>   <s:State name="down"/>   <s:State name="disabled"/>  </s:states>  <s:Path alpha="0.95" data="M 99.502 35.5 L 0.5 35.5 L 0.5 9.68 C 0.5 4.61 5.566 0.5 11.815 0.5 L 88.187 0.5 C 94.435 0.5 99.502 4.61 99.502 9.68 L 99.502 35.5 Z" ai:objID="4c09c580" winding="nonZero" x="0" y="0">   <s:fill>    <s:LinearGradient scaleX="99.0015" x="0.5" y="18">     <s:GradientEntry color="0x4E4E4E" ratio="0.5"/>     <s:GradientEntry color="0x545454" ratio="0.745455"/>     <s:GradientEntry color="0x5B5B5B" ratio="1"/>    </s:LinearGradient>   </s:fill>   <s:stroke>    <s:SolidColorStroke caps="none" color="0x6A6A6A" joints="miter" miterLimit="4" scaleMode="normal" weight="1"/>   </s:stroke>  </s:Path>  <s:Path alpha="0.95" data="M 0 23.187 L 0 4.229 C 0 4.229 22.572 -4.313 50 2.771 C 77.427 9.854 100 1.312 100 1.312 L 100 23.187 L 0 23.187 Z" ai:objID="4c177400" winding="nonZero" x="0" y="13">   <s:fill>    <s:LinearGradient rotation="270" scaleX="23.2266" x="50.0005" y="23.2266">     <s:GradientEntry ratio="0"/>     <s:GradientEntry color="0x333333" ratio="1"/>    </s:LinearGradient>   </s:fill>  </s:Path> </s:Skin> 


观察了一下,FC现在导出的皮肤根标签已经就直接是skin了,而不是sparkSkin,那么当然就可以直接给mx用了啊。
只要删去这几个部分:1、<fx:Metadata>……</fx:Metadata>
                           2、<s:states> ……<s:states>这样保留下来的就只有绘图函数代码了。
                           3、如果你也是用AI画的皮肤,你就也会有xmlns:ai=http://ns.adobe.com/ai/2009这个命名空间,删掉它,同时把代码部分里出现ai属性的地方都删除,如:ai:objID="4c177400"这种。

OK!现在就能完美把FC导出的代码化皮肤加给mx用啦。你看我说的麻烦,你操作一下就会发现,这其实很简单的。

最后再说一下,怎么在运行时动态设置皮肤的颜色等外观。运行时皮肤只能通过一种途径跟调用它的控件通信,就是getStyle()方法。用这个方法获取当前控件的一个style属性值。例如<s:GradientEntry color="0x333333" ratio="1"/> 这句就可以改成<s:GradientEntry color="{getStyle('color')}" ratio="1"/> 然后运行时去设置那个Button的color属性就可以了。

啊,打字打累了,就说这么多了吧,也不知道说明白了没,希望对看的人有帮助啊。

posted on 2010-04-09 11:16  sungo  阅读(1247)  评论(0编辑  收藏  举报