Flex4 - 自定义Spark组件-推拉式容器组件(包含皮肤和动画)
1,下面是一个自定义的Spark组件的例子,下拉展开式容器组件。点击箭头可以展开和关闭,同时有动画效果。效果图如下:


--- 组件皮肤 RevealSkinAnimated.mxml ---
--- 箭头皮肤 ArrowSkin.mxml ---
--- 箭头 OptimizedArrow.fxg ---
--- 测试类 RevealDemo.mxml ---
2,由于spark组件做到了皮肤和组件分离,所以我们只需创建个新的皮肤就可以实行不同的效果。
下面通过改变皮肤,实现了侧面推拉的容器组件,效果图如下:
--- 皮肤类 RevealSkinSidebarAnimated.mxml ---
--- 测试类 SideDemo.mxml ---

代码结构如下:

--- 组件类 Reveal.as ---
package components { import flash.events.Event; import spark.components.SkinnableContainer; import spark.components.ToggleButton; import spark.components.supportClasses.TextBase; /* Skin States */ [SkinState("open")] [SkinState("closed")] public class Reveal extends SkinnableContainer { /* Parts */ [SkinPart(required="false")] public var labelDisplay:TextBase; [SkinPart] public var openButton:ToggleButton; /* Data Model */ private var _open:Boolean = false; private var _label:String; /* States */ override protected function getCurrentSkinState():String { if(_open) return "open"; else return "closed"; } /* get/set functions */ public function set open(value:Boolean):void { _open = value; invalidateSkinState(); invalidateProperties(); } public function get open():Boolean { return _open; } public function set label(value:String):void { if(_label == value) return; _label = value; if(labelDisplay != null) labelDisplay.text = value; } public function get label():String { return _label; } /* Part Lifecycle */ override protected function partAdded(name:String,instance:Object):void { super.partAdded(name,instance); if(instance == openButton) { openButton.addEventListener(Event.CHANGE,toggleButtonChangeHandler); openButton.selected = _open; } else if (instance == labelDisplay) { labelDisplay.text = label; } } private function toggleButtonChangeHandler(e:Event):void { open = openButton.selected; } } }
<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark"> <s:states> <s:State name="closed" /> <s:State name="open" /> </s:states> <s:Rect radiusX="5" top="0" left="0" right="0" bottom="0" alpha=".9"> <s:fill> <s:SolidColor color="#E1FFBB" /> </s:fill> <s:stroke> <s:SolidColorStroke color="#BAD47F" weight="2" /> </s:stroke> </s:Rect> <s:Group left="0" top="0" right="0" bottom="5"> <s:ToggleButton id="openButton" skinClass="skins.ArrowSkin" left="5" top="5" /> </s:Group> <s:Label id="labelDisplay" left="35" top="13" right="15" lineBreak="explicit" /> <s:Group id="contentGroup" top="35" bottom="5" left="5" right="5" includeIn="open"> <s:layout> <s:VerticalLayout /> </s:layout> </s:Group> <s:transitions> <s:Transition fromState="closed" toState="open"> <s:Sequence> <s:Resize target="{this}" duration="150" /> <s:AddAction target="{contentGroup}" /> <s:Fade target="{contentGroup}" alphaFrom="0" alphaTo="1" duration="150"/> </s:Sequence> </s:Transition> <s:Transition fromState="open" toState="closed"> <s:Sequence> <s:Fade target="{contentGroup}" alphaFrom="1" alphaTo="0" duration="150" /> <s:RemoveAction target="{contentGroup}" /> <s:Resize target="{this}" duration="150" /> </s:Sequence> </s:Transition> </s:transitions> </s:Skin>
<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:skins="skins.*"> <!-- host component --> <fx:Metadata> <![CDATA[ /** * @copy spark.skins.spark.ApplicationSkin#hostComponent */ [HostComponent("spark.components.ToggleButton")] ]]> </fx:Metadata> <!-- states --> <s:states> <s:State name="up" /> <s:State name="over" stateGroups="overStates" /> <s:State name="down" stateGroups="downStates" /> <s:State name="disabled" stateGroups="disabledStates" /> <s:State name="upAndSelected" stateGroups="selectedStates, selectedUpStates" /> <s:State name="overAndSelected" stateGroups="overStates, selectedStates" /> <s:State name="downAndSelected" stateGroups="downStates, selectedStates" /> <s:State name="disabledAndSelected" stateGroups="selectedUpStates, disabledStates, selectedStates" /> </s:states> <skins:OptimizedArrow id="arrow" x="0" y="0" x.selectedStates="25" rotation.selectedStates="90" /> </s:Skin>
<?xml version="1.0" encoding="UTF-8"?> <Graphic version="1.0" xmlns="http://ns.adobe.com/fxg/2008" xmlns:fw="http://ns.adobe.com/fxg/2008/fireworks" viewHeight= "25" viewWidth= "25"> <Path winding="nonZero" data="M 24 13 C 24 19 19 24 13 24 C 7 24 2 19 2 13 C 2 7 7 2 13 2 C 19 2 24 7 24 13 Z " blendMode="normal" alpha="1"> <fill> <LinearGradient x = "13" y = "2" scaleX = "22" rotation = "90"> <GradientEntry color="#a32251" ratio="0" alpha="1"/> <GradientEntry color="#a32251" ratio="0.01" alpha="1"/> <GradientEntry color="#461f2d" ratio="0.99" alpha="1"/> <GradientEntry color="#461f2d" ratio="1" alpha="1"/> </LinearGradient> </fill> </Path> <Path winding="nonZero" data="M 24 13 C 24 19 19 24 13 24 C 7 24 2 19 2 13 C 2 7 7 2 13 2 C 19 2 24 7 24 13 Z " blendMode="normal" alpha="1"> <stroke> <SolidColorStroke color="#ffffff" weight="3"/> </stroke> </Path> <Path winding="nonZero" data="M 12 18 L 20 13 L 12 7 L 12 11 L 5 11 L 5 15 L 12 15 L 12 18 Z " blendMode="normal" alpha="1"> <fill> <SolidColor color="#ffffff" alpha="1"/> </fill> </Path> <Path winding="nonZero" data="M 21 6 C 19 4 16 2 13 2 C 7 2 2 7 2 13 C 2 15 3 18 5 20 C 5 14 11 9 21 6 Z " blendMode="normal" alpha="0.34901960784313724"> <fill> <SolidColor color="#ffffff" alpha="0.34901960784313724"/> </fill> </Path> </Graphic>
<?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" xmlns:components="components.*" > <fx:Style> @namespace components "components.*"; @namespace mx "library://ns.adobe.com/flex/mx"; @namespace s "library://ns.adobe.com/flex/spark"; components|Reveal { skinClass: ClassReference("skins.RevealSkinAnimated"); color: #849C23; } components|Reveal:open { color: #52533F; font-weight: bold; } </fx:Style> <s:VGroup horizontalAlign="contentJustify" left="40" top="40"> <components:Reveal label="Gift Options" > <s:RadioButton label="None" /> <s:RadioButton label="Include a card (free!)" /> <s:RadioButton label="Gift Wrap" /> </components:Reveal> <components:Reveal label="Other Shipping Options" > <s:RadioButton label="Ground" /> <s:RadioButton label="2-Day Super Saver" /> <s:RadioButton label="Priority Overnight" /> <s:RadioButton label="Teleportation" /> </components:Reveal> <components:Reveal label="Payment Method" > <s:RadioButton label="Send Cash" /> <s:RadioButton label="Check" /> <s:RadioButton label="PayPal" /> <s:RadioButton label="Credit Card" /> </components:Reveal> </s:VGroup> </s:Application>
下面通过改变皮肤,实现了侧面推拉的容器组件,效果图如下:

<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark"> <s:states> <s:State name="closed" /> <s:State name="open" /> </s:states> <s:Rect radiusX="5" top="0" left="0" right="-10" bottom="0" alpha=".9"> <s:fill> <s:SolidColor color="#E1FFBB" /> </s:fill> <s:stroke> <s:SolidColorStroke color="#BAD47F" weight="2" /> </s:stroke> </s:Rect> <s:Group left="0" right="5" top="0" bottom="0"> <s:ToggleButton id="openButton" skinClass="skins.ArrowSkin" left="5" top="5" scaleX="-1"/> <s:Label id="labelDisplay" rotation="90" left="9" top="35" bottom="5" /> </s:Group> <s:Group id="contentGroup" top="5" left="35" bottom="5" right="5" includeIn="open" /> <s:transitions> <s:Transition fromState="closed" toState="open"> <s:Sequence> <s:Resize target="{this}" duration="300" /> </s:Sequence> </s:Transition> <s:Transition fromState="open" toState="closed"> <s:Sequence> <s:Resize target="{this}" duration="300" /> <s:RemoveAction target="{contentGroup}" /> </s:Sequence> </s:Transition> </s:transitions> </s:Skin>
<?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" xmlns:components="components.*" > <fx:Style> @namespace components "components.*"; @namespace mx "library://ns.adobe.com/flex/mx"; @namespace s "library://ns.adobe.com/flex/spark"; components|Reveal { skinClass: ClassReference("skins.RevealSkinSidebarAnimated"); } components|Reveal:closed { color: #849C23; } components|Reveal:open { color: #52533F; } </fx:Style> <components:Reveal label="Other Shipping Options" top="0" right="0" bottom="0"> <components:layout> <s:VerticalLayout /> </components:layout> <s:RadioButton label="Ground" /> <s:RadioButton label="2-Day Super Saver" /> <s:RadioButton label="Priority Overnight" /> <s:RadioButton label="Teleportation" /> </components:Reveal> </s:Application>