`
luhantu
  • 浏览: 199715 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Flex Skin (Spark)

阅读更多

一.什么是皮肤? 为什么要定义皮肤?

皮肤是用于控制组件的外观的组件,就是说控制组件的所有可视化部分。

将组件的外观和行为分开,通过皮肤可以对可视化部分进行独立的修改,而不影响到组件的底层核心部分。

二.皮肤和css的区别

皮肤与css都是设计样式的,但是却有本质的不同。

Skin就好比一件衣服,有一个默认的款式与外观,同时也包含了一些参数,可以改变skin的默认样式。具体的应用样式,用CSS帮你细化,如:给这件衣服设置不同的颜色,不同的尺码。

三.皮肤的使用

1.FLEX默认的皮肤

1)Flash Builder 4.5 新增的主题 C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0\frameworks\themes目录下面的内容就是Flash Builder 4.5 新增的主题(theme)样式所在的位置。 包括:AeonGraphical、Halo、Mobile、Spark、Wireframe主题。SDK4.5默认的主题:Spark

2)Spark和Halo中重要的三套皮肤所在的位置

Spark组件默认皮肤的位置:C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0\frameworks\projects\spark\src\spark\skins\spark

Halo组件默认皮肤的位置: C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0\frameworks\projects\mx\src\mx\skins\halo

Spark skin for Halo皮肤的位置:C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0\frameworks\projects\sparkskins\src\mx\skins\spark

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",phone:123,email:"dd"},
				{name:"kenny2",phone:123,email:"dd"},
				{name:"kenny3",phone:123,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" />

分享到:
评论
1 楼 aosnowit 2015-07-31  
这里有一套非常不错的 SparkSkin 主题皮肤,更新很频繁!有许多不错的实用组件和组件皮肤,而且是开源的,地址:https://git.oschina.net/starfire/StarSparkSkin

相关推荐

Global site tag (gtag.js) - Google Analytics