flex4默认提供了很多效果,但是很多时候我们还是要自定义效果才能满足需求
要自定义flex4的效果需要用到两个类,Animate和AnimateInstance
自定义的效果要继承自AnimateInstance,这个类用来编写实际效果运行的代码,里面必须覆盖两个方法play()和animationUpdate(),play()方法用来初始化效果的参数,然后启动效果,animationUpdate()将在效果每次更新过程中调用,这个方法运行的就是实际执行效果的代码。
另一个类继承自Animate,这个类用来自定义效果,但是实际的效果是其内部由AnimateInstance实例来决定的。
下面用一个例子说明如何实现自定义效果
首先定义一个SlideAnimateInstance继承自AnimateInstance,这个类里有两个需要注意的地方,首先是target属性,这个属性表示当前运行效果的对象,另一个是motionPaths属性,这个集合用来存储MotionPath对象,每个MotionPath对象都定义了实际效果运行过程中改变的属性和对应的值。
import flash.display.DisplayObject; import mx.events.FlexEvent; import spark.effects.animation.Animation; import spark.effects.animation.MotionPath; import spark.effects.animation.SimpleMotionPath; import spark.effects.supportClasses.AnimateInstance; /** * 自定义滑动效果 * @author wkkyo * */ public class SlideAnimateInstance extends AnimateInstance { public var direction:String = "up"; public var offset:Number = 0; public function SlideAnimateInstance(target:Object){ super(target); } /** * 覆盖父类的play方法实现自定义效果 * */ override public function play():void{ //执行效果的组件 var t:DisplayObject = target as DisplayObject; //效果的属性 var motionPath:SimpleMotionPath = new SimpleMotionPath(); var from:Number; var to:Number; switch( direction ) { case "up": motionPath.property = "y"; from = -t.height; to = offset; break; case "right": motionPath.property = "x"; from = t.parent.width; to = t.parent.width-t.width-offset; break; case "down": motionPath.property = "y"; from = t.parent.height; to = t.parent.height-t.height-offset; break; case "left": motionPath.property = "x"; from = -t.width; to = offset; break; } motionPaths = new Vector.<MotionPath>(); motionPaths.push(motionPath); if (null != triggerEvent ){ if ( triggerEvent.type == FlexEvent.SHOW ){ motionPath.valueFrom = from; motionPath.valueTo = to; }else{ motionPath.valueFrom = to; motionPath.valueTo = from; } } super.play(); } override public function animationUpdate(animation:Animation):void{ super.animationUpdate(animation); var t:DisplayObject = target as DisplayObject; if(direction == "up" || direction == "down"){ t.y = animation.currentValue["y"] as Number; }else if(direction == "left" || direction == "right"){ t.x = animation.currentValue["x"] as Number; } } }
接下来是SlideAnimate继承自Animate,在这个类的构造方法里需要将instanceClass赋值为自定义效果类的实例,即SlideAnimateInstance,同样要覆盖两个方法initInstance()和getAffectedProperties()
import mx.effects.IEffectInstance; import spark.effects.Animate; /** * 滑动效果类 * @author wkkyo * */ public class SlideAnimate extends Animate { /* 组件滑动的方向 “上右下左” */ [Inspectable(catalog="Common", type="String",enumeration="up,right,down,left", defaultValue = "up" )] public var direction:String = "up"; /* 组件偏移量 */ public var offset:Number = 0; public function SlideAnimate(target:Object=null) { super(target); instanceClass = SlideAnimateInstance; } override protected function initInstance(instance:IEffectInstance):void { super.initInstance(instance); var inst:SlideAnimateInstance = instance as SlideAnimateInstance; inst.direction = this.direction; inst.offset = this.offset; } override public function getAffectedProperties():Array { return ["x","y"]; } }
接下来就可以在mxml中使用这个自定义的效果了
<s:WindowedApplication 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:effect="com.effect.*"> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> <effect:SlideAnimate id="slideAnimate" direction="up" /> </fx:Declarations> <s:Panel id="pan" title="从上滑出" width="200" height="300" showEffect="{slideAnimate}" hideEffect="{slideAnimate}" > </s:Panel> <s:Button label="效果" click="pan.visible=!pan.visible" right="10" /> </s:WindowedApplication>其他效果都是类似的,重点就是在play方法中设置效果的参数,然后在 animationUpdate修改对应的属性。