一.什么是皮肤? 为什么要定义皮肤?
皮肤是用于控制组件的外观的组件,就是说控制组件的所有可视化部分。
将组件的外观和行为分开,通过皮肤可以对可视化部分进行独立的修改,而不影响到组件的底层核心部分。
二.皮肤和css的区别
皮肤与css都是设计样式的,但是却有本质的不同。
Skin就好比一件衣服,有一个默认的款式与外观,同时也包含了一些参数,可以改变skin的默认样式。具体的应用样式,用CSS帮你细化,如:给这件衣服设置不同的颜色,不同的尺码。
三.皮肤的使用
1.FLEX默认的皮肤
1)Flash Builder 4.5 新增的主题 C:Program FilesAdobeAdobe Flash Builder 4.5sdks4.5.0frameworksthemes目录下面的内容就是Flash Builder 4.5 新增的主题(theme)样式所在的位置。 包括:AeonGraphical、Halo、Mobile、Spark、Wireframe主题。SDK4.5默认的主题:Spark
2)Spark和Halo中重要的三套皮肤所在的位置
Spark组件默认皮肤的位置:C:Program FilesAdobeAdobe Flash Builder 4.5sdks4.5.0frameworksprojectssparksrcsparkskinsspark
Halo组件默认皮肤的位置: C:Program FilesAdobeAdobe Flash Builder 4.5sdks4.5.0frameworksprojectsmxsrcmxskinshalo
Spark skin for Halo皮肤的位置:C:Program FilesAdobeAdobe Flash Builder 4.5sdks4.5.0frameworksprojectssparkskinssrcmxskinsspark
2.SparkSkin介绍
1)SparkSkin:是全部Spark Class的基础类,大部分可视化控件的皮肤都是SparkSkin的子类。我们通过这个SparkSkin来实现自定义控件的皮肤。
2)Skin:是SparkSkin的父类,例如:ButtonBarSkin就是Skin的子类,如果想要自定义这部分组件的皮肤,则需要使用Skin。 综上所述,也就是可以使用SparkSkin的地方,我们使用Skin一样可以达到同样的
3.皮肤的使用
1)s|CheckBox { skinClass:ClassReference("components.skins.checkBox.CheckBoxSkin"); }
2)<s:Button skinClass="components.skins.button.CreativeDeleteButtonSkin" />
3)myButton.setStyle( "skinClass",CustomEnterButtonSkin);
应用实例:
?
<?xml version="1.0" encoding="utf-8"?> <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" minWidth="955" minHeight="600" xmlns:view="com.view.*"> <fx:Declarations> <!-- Place non-visual elements (e.g.,services,value objects) here --> </fx:Declarations> <fx:Style> @namespace s "library://ns.adobe.com/flex/spark"; .testSparkButtonSkin { skinClass:ClassReference("com.skin.CustomComboBoxSkin") } s|ComboBox { skinClass:ClassReference("com.skin.CustomComboBoxSkin") } </fx:Style> <fx:Script> <![CDATA[ import com.skin.CustomComboBoxSkin; import mx.collections.ArrayCollection; import mx.collections.ArrayList; import spark.components.ComboBox; import spark.events.IndexChangeEvent; import spark.skins.spark.ApplicationSkin; [Bindable]public var dataProvider:ArrayList = new ArrayList([{name:"kenny",phone:123,email:"dd"},{name:"kenny1",{name:"kenny2",{name:"kenny3",email:"dd"}]); protected function button1_clickHandler(event:MouseEvent):void { test.setStyle("skinClass",Class(CustomComboBoxSkin)); } ]]> </fx:Script> <s:layout> <s:VerticalLayout/> </s:layout> <s:ComboBox dataProvider="{dataProvider}" labelField="name" styleName="testSparkButtonSkin"/> <s:ComboBox dataProvider="{dataProvider}" labelField="name" skinClass="com.skin.CustomComboBoxSkin"/> <s:ComboBox dataProvider="{dataProvider}" labelField="name" id="test"/> <s:ComboBox dataProvider="{dataProvider}" labelField="name"/> <s:Button click="button1_clickHandler(event)"/> </s:Application>?Skin 实例:
?
?
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:fb="http://ns.adobe.com/flashbuilder/2009" alpha.disabled=".5" xmlns:mx="library://ns.adobe.com/flex/mx"> <!-- host component --> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.ComboBox")] ]]> </fx:Metadata> <fx:Script fb:purpose="styling"> <![CDATA[ private var paddingChanged:Boolean; private var cornerRadiusChanged:Boolean; private var cornerRadius:Number = 0; /* Define the content fill items that should be colored by the "contentBackgroundColor" style. */ static private const contentFill:Array = ["bgFill"]; /** * @private */ override public function get contentItems():Array {return contentFill}; /** * @private */ override protected function commitProperties():void { super.commitProperties(); if (paddingChanged && textInput) { // Push padding styles into the textDisplay var padding:Number; padding = getStyle("paddingLeft"); if (textInput.getStyle("paddingLeft") != padding) textInput.setStyle("paddingLeft",padding); padding = getStyle("paddingTop"); if (textInput.getStyle("paddingTop") != padding) textInput.setStyle("paddingTop",padding); padding = getStyle("paddingRight"); if (textInput.getStyle("paddingRight") != padding) textInput.setStyle("paddingRight",padding); padding = getStyle("paddingBottom"); if (textInput.getStyle("paddingBottom") != padding) textInput.setStyle("paddingBottom",padding); paddingChanged = false; } if (cornerRadiusChanged) { cornerRadiusChanged = false; var cr:Number = getStyle("cornerRadius"); if (openButton) openButton.setStyle("cornerRadius",cr); if (textInput) textInput.setStyle("cornerRadius",cr); } } /** * @private */ override public function styleChanged(styleProp:String):void { var allStyles:Boolean = !styleProp || styleProp == "styleName"; super.styleChanged(styleProp); if (allStyles || styleProp.indexOf("padding") == 0) { paddingChanged = true; invalidateProperties(); } if (allStyles || styleProp == "cornerRadius") { cornerRadiusChanged = true; invalidateProperties(); } } ]]> </fx:Script> <s:states> <s:State name="normal" /> <s:State name="open" /> <s:State name="disabled" /> </s:states> <!--- The PopUpAnchor control that opens the drop-down list. <p>In a custom skin class that uses transitions,set the <code>itemDestructionPolicy</code> property to <code>none</code>.</p> --> <s:PopUpAnchor id="popUp" displayPopUp.normal="false" displayPopUp.open="true" includeIn="open" left="0" right="0" top="0" bottom="0" itemDestructionPolicy="auto" popUpPosition="below" popUpWidthMatchesAnchorWidth="true"> <!--- This includes borders,background colors,scrollers,and filters. @copy spark.components.supportClasses.DropDownListBase#dropDown --> <s:Group id="dropDown" maxHeight="134" minHeight="22" > <!-- drop shadow --> <!--- @private --> <s:RectangularDropShadow id="dropShadow" blurX="20" blurY="20" alpha="0.45" distance="7" angle="90" color="#ff0000" left="0" top="0" right="0" bottom="0"/> <!-- border --> <!--- @private --> <s:Rect id="border" left="0" right="0" top="0" bottom="0"> <s:stroke> <!--- @private --> <s:SolidColorStroke id="borderStroke" weight="1"/> </s:stroke> </s:Rect> <!-- fill --> <!--- Defines the appearance of drop-down list's background fill. --> <s:Rect id="background" left="1" right="1" top="1" bottom="1" > <s:fill> <!--- @private The color of the drop down's background fill. The default color is 0xFFFFFF. --> <s:SolidColor id="bgFill" color="0xff0000" /> </s:fill> </s:Rect> <mx:DataGrid id="dataGrid" rowCount="6" left="0" top="0" bottom="0" right="0" hasFocusableChildren="true"> <mx:columns> <mx:DataGridColumn dataField="name" headerText="Name"/> <mx:DataGridColumn dataField="phone" headerText="Phone"/> <mx:DataGridColumn dataField="email" headerText="Email"/> </mx:columns> </mx:DataGrid> </s:Group> </s:PopUpAnchor> <!--- The default skin is ComboBoxButtonSkin. @copy spark.components.supportClasses.DropDownListBase#openButton @see spark.skins.spark.ComboBoxButtonSkin --> <s:Button id="openButton" width="19" right="0" top="0" bottom="0" focusEnabled="false" skinClass="spark.skins.spark.ComboBoxButtonSkin" /> <!--- @copy spark.components.ComboBox#textInput --> <s:TextInput id="textInput" left="0" right="18" top="0" bottom="0" skinClass="spark.skins.spark.ComboBoxTextInputSkin"/> </s:SparkSkin>?Skin 讲解:
? ?<fx:Metadata>
? ? ? ? <![CDATA[?
? ? ? ? [HostComponent("spark.components.ComboBox")]
? ? ? ? ]]>
? ? </fx:Metadata>?
HostComponent 元数据指向您要设计外观的组件。
? ? <s:states>
? ? ? ? <s:State name="normal" />
? ? ? ? <s:State name="open" />
? ? ? ? <s:State name="disabled" />
? ? </s:states>
定义RadioButton的一组外观状态
<s:Ellipse x="0" y="0" width="20" height="20">
? ? ? ? ? ??<s:fill>
? ? ? ? ? ? ? ? ? ??<s:LinearGradient x="10" y="20" rotation="270" scaleX="20">
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<s:GradientEntry color="#333333" ratio="0"/>
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<s:GradientEntry color="#737373" ratio="1"/>
? ? ? ? ? ? ? ? ? ? ?</s:LinearGradient>
? ? ? ? ? ? ? </s:fill>
</s:Ellipse>
Ellipse: 画一个椭圆形
fill: 设置填充方式
LinearGradient: 设置渐变颜色
rotation:设置过滤方向,这里是从下到上
GradientEntry:设置渐变颜色
4.定义皮肤时的常用类
Flex中基本形状有三种:
Rect矩形(圆角矩形)
Ellipse椭圆(圆形)
Line直线
Flex的复杂图形使用Path来绘制
Flex
使用fill对图形本体进行上色,
使用stroke对图形边框进行上色,
而fill(填充)和stroke(画笔)有三种上色方法:
fill — SolidColor(色块),RadialGradient(径向渐变),LinearGradient(线性渐变)。
stroke — SolidColorStroke(实线),RadialGradientStroke(径向渐变),LinearGradientStroke(线性渐变)。 Flex中常用的效果滤镜有7个: GlowFilter(单色发光滤镜) BlurFilter(模糊滤镜) DropShadowFilter(阴影滤镜) BevelFilter(斜角滤镜) GradientGlowFilter(彩色发光滤镜) GradientBevelFilter(彩色斜角滤镜) ColorMatrixFilter(色彩响应矩阵滤镜)
?
四.halo包使用定义的皮肤
看以下的代码:
<fx:Style>
??? .sparkButtonStyle {
???????? skin: ClassReference("com.rianote.flex.skin.KButton");
??? }
</fx:Style>
<mx:Button label="我是halo组件" styleName="sparkButtonStyle"/>
KButton继承是spark for halo皮肤下的皮肤。
再让我们对比一下spark组件的写法:
<fx:Style>
Button {?
??? skinClass: ClassReference("com.rianote.flex.skin.KButton");?
}
</fx:Style>
<s:Button label="我是spark组件" skinClass="com.rianote.flex.skin.KButton" />