当前位置: > > > Flex4 - 自定义Spark组件-推拉式容器组件(包含皮肤和动画)

Flex4 - 自定义Spark组件-推拉式容器组件(包含皮肤和动画)

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

代码结构如下:


--- 组件类 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;	
		}
	}		
}

--- 组件皮肤 RevealSkinAnimated.mxml ---
<?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>

--- 箭头皮肤 ArrowSkin.mxml ---
<?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>

--- 箭头 OptimizedArrow.fxg ---
<?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>

--- 测试类 RevealDemo.mxml ---
<?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>

2,由于spark组件做到了皮肤和组件分离,所以我们只需创建个新的皮肤就可以实行不同的效果。
下面通过改变皮肤,实现了侧面推拉的容器组件,效果图如下:


--- 皮肤类 RevealSkinSidebarAnimated.mxml ---
<?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>

--- 测试类 SideDemo.mxml ---
<?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>
评论0