Flex行为控制实现了对可视化组件的某种 事件响应效果的定义和控制。行为控制由效果触发器和效果对象组成,即当Flex可视化组件响应一个事件后,通过触 发器触发一个特定的效果,这个效果通常会持续一小段时间,一般以微秒为单位,如组件的淡入淡出、尺寸缩放、位置移动等。默认情况下,Flex是不会对可视化组件进行任何的行为控制和处理的,因此使用行为控制时要进行明确的定义。 3.1.1 Flex行为控制概述 Flex行为控制支持通过一个效果触发器触 发多种效果。我们在软件开发过程中经常会用到某个事件处理会引发大量的组件效果,如单击一个按钮后,按钮本身淡出消失,按钮所在的容器窗体尺寸改变等。 Flex行为控制中的效果触发器与Flex可视化组件的事件机制是不相同的。虽然两者都会对可视化组件的动作处理进行捕捉,但是效果触发器 与效果对象相关联,对组件本身进行效果处理,而事件机制则会发送一个事件到指定的事件监听器,通过事件监听器完成功能性的业务操作。 Flex行为控制通过MXML和ActionScript都 可以进行定义和控制。在MXML中可以通过行为控制组件定义行为类型和效果类型,然后 通过可视化组件的效果触发器定义使行为控制生效。下面的代码定义了基于MXML的行为控制: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:WipeLeft id="myBehavior" duration="1000"/> <mx:Button id="myButton" label="OK" mouseDownEffect="{myBehavior}"/> </mx:Application> 这段代码通过MXML标签<mx:WipeLeft>创建了一个行为组件WipeLeft,并定义 效果持续时间为1000微秒,在一个Button组件的定义中通过数据绑 定设定mouseDownEffect属性,指定了WipeLeft所对 应的触发器为鼠标按下,WipeLeft组件对应一个条形过渡的效果,当触发器触发时,对应的组件会从左到右平移 出现,对应这段代码,当用鼠标单击OK按钮后,按钮会从左到右逐渐平移出现,过程持续1000微秒。 同样,我们也可以使用 ActionScript进行Flex行为控制的创建、修改和效果设置。应用ActionScript,也可以使用效果触发器来触发相应的效果,不仅如此,还可以通过调用play方法强制执行某种行为效果。 下面的代码通过 ActionScript定义了行为控制: <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="createEffect(event);" > <mx:Script> <![CDATA[ import mx.effects.*; private var myWL:WipeLeft; private function createEffect(eventObj:Event):void { myWL = new WipeLeft(); myWL.duration = 1000; myButton.setStyle('mouseDownEffect', myWL); myOtherButton.setStyle('mouseDownEffect', myWL); } ]]> </mx:Script> <mx:Button id="myButton" label="OK"/> <mx:Button id="myOtherButton" label="Cancel"/> </mx:Application> 上述代码通 过ActionScript脚本创建了一个WipeLeft类型的对象myWL,并通过setStyle方法对两个Button 组件的效果触发器mouseDownEffect进行了行为控制设定,其运行效果与通过MXML方式创建行为控制是一致的。 Flex的行为控制支持两种实现效果的方式——工厂类和实例类。 工厂类 : 工厂类在执行效果处理时会为目标对象创建一个效果对象 , 在应用程序中 , 我们可以创建工厂类型的实例 , 如 <mx:WipeLeft id= “ myBehavior ” duration= “ 1000 ” /> 创建了 WipeLeft 类型的实例。通过 id 即可以在效果触发器中设置效果。 实例类: 实例类方式实现了效果对象的逻辑,当效果触发器被触或调用 play 方法时进行效果调用,工厂类型会 为目标对象创建一个实例效果对象。当效果结束时, Flex 会销毁掉该实例效果对象。 一般情况 下,我们可以直接使用工厂类的方式来进行可视化组件的行为控制,实例类处理需要更加细化;而当我们需要对效果类型进行定制化处理时,则需要对实例类本身进 行调用和处理。 了解了Flex的行为控制机制后,来看一看具体被Flex所支持的效果类型和效果触发器类 型都有哪些,请参考表3.1和3.2。 表3.1 Flex行为控制—— 效果类型
效果类型 | 效果描述 | AnimateProperty | 动画属性。可以设置可视化组件的某个数值属性,如hight、weight,指定属性名称、动画起始值、动画最终值后,即可实现组件某个属性的动画效果 | Blur | 模糊效果 | Dissolve | 溶解效果,通过alpha属性设置组件的透明度,实 现组件的溶解出现或消失 | Fade | 淡入淡出效果 | Glow | 光亮效果 | Iris | 定义组件扩展或缩小的动画效果 | Move | 定义组件移动的动画效果,可以定义移动的时间周期,组件的布局方式必须为绝对定位布局 | Pause | 暂停效果 | Resize | 尺寸变化效果 | Rotate | 旋转效果 | SoundEffect | 声音效果,支持MP3文件的播放,实现与组件进行交 互时的声音效果控制 | WipeLeft WipeRight WipeUp WipeDown | 条形过渡效果,四种类型分别定义了组件从左到右、从右到左、从上到下、从下到上的条形过渡效果 | Zoom | 缩放效果 |
表3.2 Flex行为控制—— 效果触发器类型
效果触发器类型 | 触发器描述 | addedEffect | 组件被添加到另一个容器组件之中时触发 | creationCompleteEffect | 组件创建完成时触发 | focusInEffect | 组件获得焦点时触发 | focusOutEffect | 组件失去焦点时触发 | hideEffect | 组件隐藏时触发 | mouseDownEffect | 鼠标按下时触发 | mouseUpEffect | 鼠标抬起时触发 | moveEffect | 组件被移动而改变定位时触发 | resizeEffect | 组件尺寸变化时触发 | rollOutEffect | 鼠标移出组件范围时触发 | rollOverEffect | 鼠标移入组件范围时触发 | showEffect | 组件显示时触发 |
3.1.2 在MXML中使用行为控制 略…… 3.1.3 在ActionScript中使用行为控制 在ActionScript代码中可以实现对Flex行为控制的操作,可以通过ActionScript类创建行为控制的效果对象,并使用效果对象的target 属性指定目标可视化组件。这样可以不经过效果触发器,而是通过事件监听器进行效果处理。 通过ActionScript的事件监听器机制,可以把行为控制与事件监听结合在一起,当某些行为控制需要进行数据访问或与ActionScript对象进行交互时,通过效果触发器往往不太方便,这时就可以利用事件监听器控制效果对象的play方法实现行为控制。 示例3.2 使用ActionScript进行行为控制 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="createEffect(event);"> <mx:Script> <![CDATA[ import mx.effects.Resize private var resizeLarge:Resize = new Resize(); private function createEffect(eventObj:Event):void { //效果对象初始化 //分别设置目标组件、目标宽度、目标高 度和效果响应时间 resizeLarge.target = button2; resizeLarge.widthTo = 200; resizeLarge.heightTo = 60; resizeLarge.duration = 1000; } ]]> </mx:Script> <mx:Button id="button1" label="按钮A" width="100" height="30" fontSize="12" click=" resizeLarge.end();resizeLarge.play();"/> <mx:Button id="button2" label="按钮B" width="100" height="30" fontSize="12" click="button2.width=100;button2.height=30;"/> </mx:Application> 示例3.2通过ActionScript创建了Resize对象并对一个按钮组件进行了行为控制,通过对象的target属性指定了目标按钮button2,对于效果对象的初始化通过程序加载监听器creationComplete实现。在Button组件button1的click事件监听器中定义 执行了两条ActionScript命令:resizeLarge.end()用于控制结束前一次的效果,在这里起到了状态重置的作用;resizeLarge.play()则用于执行效果。Button组 件button2则定义了对本身的尺寸重置。运行效果如图3.3和3.4所示,当用鼠标单击 “按钮A”后,按钮B会表现出放大的效果,单击按钮B,则按钮B本身返回原始尺寸大小。 图3.3 使用ActionScript进行行为控制(1) 图3.4 使用ActionScript进行行为控制(2) 3.1.4 可视化组件效果控制 1. 效果的事件处理 所有的效果 对象都支持两个事件:effectStart和effectEnd,分别 在效果开始和效果结束的时候进行事件触发。 effectStart : 当效果开始时触发事件,事件对象的 type 属性为 EffectEvent.EFFECT_START 。 effectEnd : 当效果结束时触发事件,效果结束包括效果正常执行完毕或通过调用 end 方法打断。时间对象的 type 属性为 EffectEvent.EFFECT_END 。 Flex通过效果对象的target属 性来确定事件触发的对象。因此,当仅定义一个target的目标组件时,Flex只会触发一个effectStart事件和一个effectEnd事件;当定义了多个target的目标组件时,Flex也会 触发多个effectStart事件和effectEnd事件。 传送到事件 监听器中的事件对象类型为EffectEvent,同样这个事件类型是Event 类型的子类,集成了Event类型所有的属性和方法,如target、 type等。EffectEvent类型还定义了一个新的属性effectInstance。关于EffectEvent属 性的详细描述如下。 target : target 属性用于引用触发事件的对象,即效果对象。 type : type 属性用于判断当前事件类型是 EffectEvent.EFFECT_START 还是 EffectEvent. EFFECT_END 。 effectInstance : effectInstance 属性用于引用一个 EffectInstance 实例类对象,即效果对象的实例类 应用方式, Flex 为 target 属性指定的每一个目标组件都创建一 个效果实例对象,可以通过 effectInstance.target 进行引用。 示例3.3 效果对象的事件处理 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" > <mx:Script> <![CDATA[ import mx.effects.*; import mx.events.EffectEvent; import mx.core.UIComponent; private function endSlowFadeEffectListener(eventObj:EffectEvent):void { var effectObj:Effect = Effect(eventObj.target); var effectTarget:UIComponent = UIComponent(eventObj.effectInstance.target); myTA.text = myTA.text + effectTarget.id+ ' 效果事件触发: '; myTA.text = myTA.text + " " + eventObj.type + '/n'; } ]]> </mx:Script> <mx:Fade id="slowFade" duration="2000" effectEnd="endSlowFadeEffectListener (event);"/> <mx:HBox fontSize="12"> <mx:VBox> <mx:Button id="buttonA" label="按钮A" creationCompleteEffect="{slowFade}"/> <mx:Button id="buttonB" label="按钮B" creationCompleteEffect="{slowFade}"/> <mx:Button id="buttonC" label="按钮C" creationCompleteEffect="{slowFade}"/> <mx:Button id="buttonD" label="按钮D" creationCompleteEffect= "{slowFade}"/> </mx:VBox> <mx:TextArea id="myTA" height="125" width="250"/> </mx:HBox> </mx:Application> 示例3.3对4个按钮组件添加了同一个效果触发器,相当于对 Fade效果对象slowFade指定了4个目标组件,同时对 slowFade对象进行了事件监听处理,当效果完成时在一个TextArea上输出事件信息,效果如图3.5所示。 图3.5 效果对象的事件控制 2. 数据效果处理 Flex可视化组件中的数据容器类组件都通过Data Provider读取数据,并且按照一定的形式在组件上输出显示。我们通过集合类(数组对象)方式创建Data Provider所需要的数据结构,通常基于ArrayCollection或XMLListCollection。 数据容器类 组件在数据的输出控制上通过条目绘图器(Item Renderer)来实现,Flex为数据的效果处理方面通过List类型和TileList类型的组件的条目绘图器提供了支持。在数据容器类组件的Data Provider内容发生改变时(如增加新的数据条目),Flex即可以支持实现如淡 入淡出的效果。 在默认情况 下,数据容器类组件不使用任何效果,因此我们需要定义组件的itemChangeEffect属性来设置条目变化 的效果。为List和TileList类型的 组件分别可以使用DefaultListEffect和DefaultTileListEffect进行设置,这两个类型的效果控制可以使用MXML标签<mx:DefaultListEffect>和<mx:DefaultTileListEffect>直接进行定义,并通过相应的属性指定触发的效果类型。 示例3.4 使用数据效果 <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.effects.DefaultListEffect; import mx.collections.ArrayCollection; [Bindable] private var myDP:ArrayCollection = new ArrayCollection (['Flex','Flash','Life Cycle','Cold Fusion','Struts']); private function deleteItem():void { var toRemove:Array = []; for (var i:int=0; i<list0.selectedItems.length; i++) toRemove.push(list0.selectedItems[i]); for (i=0; i<toRemove.length; i++) myDP.removeItemAt(myDP.getItemIndex(toRemove[i])); } private var zcount:int = 0; private function addItem():void { myDP.addItemAt("NEW" + zcount++, myDP.length); } ]]> </mx:Script> <mx:DefaultListEffect id="myDLE" fadeOutDuration="1000"/> <mx:VBox fontSize="12"> <mx:List id="list0" width="165" dataProvider="{myDP}" variableRowHeight="true" fontSize="24" allowMultipleSelection="true" itemsChangeEffect="{myDLE}"/> <mx:HBox> <mx:Button label="删除条目" click="deleteItem();"/> <mx:Button label="添加条目" click="addItem();"/> </mx:HBox> </mx:VBox> </mx:Application> 示例3.4对一个List组件设置了淡入淡出的条目变化效 果,如图3.6所示,当删除掉“Cold Fusion”条目时,该条目会逐渐消失,添加条目时则会逐渐出现新条目。程序中通过定义DefaultListEffect实现了默认的淡入淡出效果。 图3.6 数据效果处理 3. 禁用容器组件的布局控制 Flex默认的布局控制会在容器组件的子组件发生变化时对整个布局进行更新,这往往会给行为控制的效果带 来影响。如Zoom、Resize等效果会对 组件的尺寸大小和定位信息进行修改,容器组件会感知到子组件的变化从而进行布局更新,随之而来的是其他所有子组件都被重置了,效果也被重置。这就造成了一 个组件的效果引发布局重置、布局重置引发了其他所有组件的效果重置,最后的结果是其他组件的效果消失了。 为了避免这 种情况的发生,我们需要禁用容器组件的布局控制,以实现可视化组件效果状态的维持。通过设置容器组件的autoLayout 属性为false即可以禁用布局控制,但是需要注意,autoLayout 属性只会对直接下级组件生效。如我们在Panel里面加入VBox,VBox中的组件如果要禁用布局控制,则必须设置VBox的autoLayout属性为 false,而不能通过Panel组件进行设置。 默认情况 下,容器组件的autoLayout值为true,即为子组件进行自动布 局控制。这样我们对子组件设置Zoom效果、Move效果都会造成布局更新,容器组件布局更新会按照指定的对齐方式对组件进行布局,默认会向左上方对齐,并根据子组件的尺寸调整容器组件本身的尺 寸大小。一旦我们禁用了autoLayout属性,那么容器组件会取消一切相关的更新操作,如果子组件的尺寸超过 容器组件的限制时,容器组件会自动添加水平或垂直方向的滚动条。 4. 设置效果缓存策略 缓存策略通 常都用于解决因某种原因造成的大量数据交互而降低效率的问题,Flex行为控制支持对效果的缓存加速,通过位图缓 冲技术来实现。在运行平台Adobe Flash Player上即支持位图缓冲技术,用以提高动画效果的速度,因此,Flex中的组件行为控制也可以通过这种技术 实现效果加速,从而使行为控制更加平滑。在Flex的行为控制应用中,位图缓冲技术用于处理绘图方式不变的组件的 效果。 如Fade效果会通过组件的alpha属性(透明度)逐渐变化实现淡入淡出 的效果、Move属性通过改变组件的x、y属性来实现组件移动的效 果,类似的这些效果都不会对组件本身的绘制进行改变,因此可以通过位图缓冲技术对其进行优化。 另一方面, 一部分效果由于会改变组件本身的绘图方式,因此不能使用位图缓冲技术,如Zoom效果、Resize效果等,当组件的尺寸发生改变时,组件本身会被绘图器进行重新绘制,因此无法再使用位图缓冲来进行 效果优化。 位图缓冲技 术通过设定静态属性UIComponent.cachePolicy来定义,可以看出这个属性依赖于最顶层的可视 化组件基类UIComponent,属于底层的策略机制,可以对cachePolicy 属性设定为下列3个值。 CachePolicy.ON :效果对象一直被执行位图缓冲。 CachePolicy.OFF :效果对象关闭位图缓冲。 CachePolicy.AUTO : 自动处理,由 Flex 决定何时使用位图缓冲,是 cachePolicy 属性的默认值。 当策略为CachePolicy.AUTO时,Flex会通过一些规则来设定可视化组件的cacheAsBitmap属性。当目标组件的效果对象至少有一个不支持位图缓冲时,设置该组件的cacheAsBitmap属性为false;否则当一个或多个组件上的效果对象都支 持位图缓冲时,则设置该组件的cacheAsBitmap属性为true。 一般情况 下,我们不需要对缓存策略进行设定,但某些情况下我们可能遇到大量的可缓存效果对象,而在Flex默认的 CachePolicy.AUTO状态下效率受到影响时,则需要对缓存策略进行修改。 |