在Flex4中引入了全新的皮肤机制:Spark,那么在这个教程里将带领大家制作一个Spark的图标按钮,原文地址:
http://www.themorphicgroup.com/blog/2009/06/18/how-to-create-a-spark-ico...
在使用MXML2009的Spark组件的时候,你可能已经注意到,按钮并没有一个“icon”的属性可供设置。所以如果你想让这个按钮显示一个图标,应该怎么办呢?
一个解决方法是把这个图标放到你的按钮的皮肤里面,但是它要求你必须创建多个皮肤和多个图标。
另一个解决方法是把一个图片组件作为按钮。当然,这个按钮我们也要实现在不同的鼠标状态下,显示不同的图标。我们可以使用鼠标事件的侦听器来切换图片组件的源地址。遗憾的是,图片中的透明像素部分,可能是导致鼠标事件不能正常工作的原因。要避免这个问题,我们需要遵循以下的步骤来创建一个自定义的组件。
创建一个新的IconButton类,并扩展自spark.components.Button
package com.tmg.components { import spark.components.Button; //icons [Style ( name= "iconUp", type= "*" ) ] [Style ( name= "iconOver", type= "*" ) ] [Style ( name= "iconDown", type= "*" ) ] [Style ( name= "iconDisabled", type= "*" ) ] //paddings [Style ( name= "paddingLeft", type= "Number" ) ] [Style ( name= "paddingRight", type= "Number" ) ] [Style ( name= "paddingTop", type= "Number" ) ] [Style ( name= "paddingBottom", type= "Number" ) ] public class IconButton extends Button { public function IconButton ( ) { super ( ); } } }
在这个类的里面,我们定义了样式的元数据标签(Style Metadata),来让Flash Builder知道在添加到这个按钮的样式属性里面,哪些样式是可用的。针对这个组件,我们想允许开发者针对不同的按钮的状态给予不同的图片显示,同时我们也想让开发者可以定义按钮内部的元件与这个按钮的边距。
创建一个mxml的皮肤组件
<s :SparkSkin xmlns :fx= "http://ns.adobe.com/mxml/2009" xmlns :s= "library://ns.adobe.com/flex/spark" xmlns :mx= "library://ns.adobe.com/flex/halo" currentStateChanging= "onCurrentStateChanging(event)" > <fx :Metadata > [HostComponent ( "com.freckle.oceania.client.view.components.IconButton" ) ] </fx :Metadata > <fx :Script > <! [CDATA [ import mx.events.StateChangeEvent; private function onCurrentStateChanging (event :StateChangeEvent ) : void { switch (event.newState ) { case "up" : setIcon ( "iconUp" ); break; case "over" : setIcon ( "iconOver" ); break; case "down" : setIcon ( "iconDown" ); break; case "disabled" : setIcon ( "iconDisabled" ); break; } } if (hostComponent. getStyle ( type ) != null ) { icon. source = hostComponent. getStyle ( type ); } } ] ] > </fx :Script > <s :layout > <s :BasicLayout /> </s :layout > <s :states > <s :State name= "up" /> <s :State name= "over" /> <s :State name= "down" /> <s :State name= "disabled" /> </s :states > <s :Rect left= "0" right= "0" top= "0" bottom= "0" width= "69" height= "20" radiusX= "2" radiusY= "2" > <s :stroke > <s :SolidColorStroke id= "outline" weight= "1" /> </s :stroke > <s :fill > <mx :LinearGradient > <mx :GradientEntry color= "#ffffff" ratio= "0" /> <mx :GradientEntry color= "#cccccc" ratio= "1" /> </mx :LinearGradient > </s :fill > </s :Rect > <s :Group horizontalCenter= "0" verticalCenter= "0" > <s :layout > <s :HorizontalLayout paddingBottom= "{ hostComponent.getStyle('paddingBottom')}" paddingTop= "{ hostComponent.getStyle('paddingTop')}" paddingLeft= "{ hostComponent.getStyle('paddingLeft')}" paddingRight= "{ hostComponent.getStyle('paddingRight')}" /> </s :layout > <mx :Image id= "icon" source= "{hostComponent.getStyle('iconUp')}" verticalCenter= "0" alpha= "{(this.currentState == 'up')?.5:1}" /> <s :SimpleText text= "{hostComponent.label}" verticalCenter= "0" includeInLayout= "{( hostComponent.label != '' )}" visible= "{( hostComponent.label != '' )}" /> </s :Group > </s :SparkSkin >
首先,你可能已经注意到元数据标签(Metadata tag)声明了一个Hostcomponent。这是非常重要的,因为它可以让皮肤组件知道那些组件会应用这个皮肤。注意Simple Text组件的text属性设置为hostComponent的标签(label)属性。
在这个代码片段中另一个关键的元件是事件的侦听器,用来侦听状态的改变。正如你所猜想的那样,hostComponent会根据不同的鼠标状态来改变按钮的皮肤的状态。通过侦听这个事件,我们可以改变用作图标的图片组件的源地址属性。
让我们来做下一步操作...
使用这个新生成的组件
<components :IconButton width= "100%" iconUp= "assets/images/icons/toolbar/arrow_out.png" iconDisabled= "assets/images/icons/toolbar/arrow_out_disabled.png" fontFamily= "Times" fontWeight= "bold" skinClass= "com.tmg.skins.IconButtonSkin" paddingLeft= "5" paddingTop= "5" paddingRight= "5" paddingBottom= "5" />
在使用你创建的这个皮肤的时候,请确保你设置了skinClass属性。在这个示例中我们只是设置了iconUP和iconDisabled属性。因为在之前的代码中我们已经明确了这个皮肤的icon属性,所以这个皮肤只能使用我们已经声明的图标。同样对Label来说,我们同样可以设置皮肤来让label的文本是空的时候不显示文本组件,但是在这个示例里面我们还是让它显示了。
你可以从下面的地址观看这个实例的视频教程:
https://xd.adobe.com/#/videos/video/165