首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 媒体动画 > flex >

Flex事件机制详细讲授

2012-09-01 
Flex事件机制详细讲解第一、Flex事件简介事件贯穿于Flex应用开发的全过程。事件是ActionScript 3.0中最重要

Flex事件机制详细讲解

第一、Flex事件简介事件贯穿于Flex应用开发的全过程。事件是ActionScript 3.0中最重要的部分之一,也是Flex应用程序开发的核心基础。本章将在DOM 3的基础上详细讲解ActionScript 3.0和Flex中的事件机制。第二、一切从事件开始
利用事件处理,可以方便地响应和处理用户输入和系统事件。Flex事件模型不仅方便,而且符合标准,新的事件模型基于文档对象模型(DOM,Document Object Model)第3级事件规范,为Flex程序员提供了强大而直观的事件处理工具
?第三、事件简介
什么是事件呢?我们去商店里买鞋子时,选择好鞋子后,告诉销售人员鞋子的款式、号码、付款,然后服务员将符合购买要求的鞋子交给我们。这样就完成了一个事件的流程。但是如何找到售货员买鞋子,售货员拿什么样的鞋子给客户,都是事件要处理的事情。
对于Flex而言,其重要的部分就是与用户进行交互。用户的操作,例如键盘输入、鼠标点击等引起界面的响应,然后在内部进行一系列的操作,最终返回用户需求的信息。简单的过程,即包含了事件的核心思想。用户的操作触发了某个事件,同时产生该事件的信息,通知相关的对象进行处理。其中,如何发起消息、传递消息是Flex非常关键的问题。
?第四、DOM 3事件机制
DOM 3的事件模型是非常简单的,符合我们日常思考的习惯。在上一节开头所举的买鞋的例子中,买鞋的人(客户)可以看作事件发送者(Event Dispatcher),买鞋的过程可以看作事件,而销售人员即事件侦听器(Event Listener)。买鞋可以看作事件的类型(Type)。买鞋的个人即事件的目标(Target)
DOM 3事件机制包含4个部分:注册事件侦听器、发送事件、侦听事件、移除事件侦听器。这4个部分贯穿整个事件的发生和结束。
?第五、ActionScript 3.0中的事件机制
在Flex的事件机制中ActionScript扮演了非常重要的角色。所以在介绍Flex事件机制前,需要对ActionScript 3.0中的事件机制进行简要的了解。
在ActionScript 3.0中,每个事件都由一个事件对象表示。事件对象是Event类或其某个子类的实例。事件对象不但存储有关特定事件的信息,还包含操作事件对象的方法。例如,当Flash Player检测到鼠标单击时,它会创建一个MouseEvent类的实例,表示发生鼠标单击事件。
1.ActionScript 3.0事件特点
2.与ActionScript 2.0的不同
? 第六、Flex中的事件机制
Flex应用程序是基于事件驱动的。它主要描述了用户页面与用户之间如何进行交互。Flex中的事件可以由外设触发,例如键盘、鼠标,或者与服务器进行数据交互时,如web service和remoteObject调用的返回。事件都是由系统的变化引起,比如:组件的创建或者改变大小。所有用户与应用交互都会产生事件。用户没有直接与应用交互也可能产生事件,比如:数据装载完毕。
Flex的事件处理与ActionScript 3.0是密不可分的。表面上看,Flex的事件处理界面与用户的交互,但当交互事件发生后,其内部处理机制还是按照ActionScript 3.0的事件机制,依靠event类完成。但是为了更直观的理解Flex的事件处理流程,不再将Flex与ActionScript 3.0的事件机制分开讲述。
? 第七、事件流
AcrionScript 3.0引入了全新的事件流机制,事件流是与显式列表(Display List)紧密结合在一起的。一旦用户界面中的组件发生事件,Flash Player发出的事件对象在显示列表中进行传递,形成事件流。本节对AcrionScript 3.0中的事件流进行介绍。
? 第八、什么是事件流
事件流说明事件对象如何在显示列表中穿行。如果显示界面嵌套使用组件,在子组件接受事件时,就可以将事件层层上传至它的父容器、根容器。下面的例中利用Flex中的可视化组件说明事件流机制。该例子的显式界面包含三个容器和一个按钮,如图所示。Flex事件机制详细讲授
第九、事件流机制
事件流机制可以分为3个阶段,按照先后发生的顺序如下所示。
捕获阶段(Capture phase):从顶部(如root)到目标。
目标阶段(Target phase):到达目标。
冒泡阶段(Bubbling phase):从目标到顶部。
捕获阶段的节点顺序是从父节点到子节点的,而上浮阶段刚好相反。捕获事件默认是关闭的,也就是说如果要捕获事件,必须显式指定在捕获阶段进行处理。每一个Event都有target和currentTarget属性,帮助跟踪事件传播的过程。
对于Event对象来说,eventPhrase属性表示正处于的阶段:1表示捕获阶段;2表示目标阶段;3表示冒泡阶段。在对事件添加了事件侦听器后,如果当前侦听的显式对象即发生事件的对象,则在目标阶段调用事件侦听器,否则在冒泡阶段才会调用事件侦听器。如果需要在捕获阶段调用事件侦听器,则修改useCapture属性。
并不是每个事件都会上浮,只有事件本身支持上浮且event对象的bubbles属性为true时才可以上浮。详细的参数可以参考event类属性。
? 第十、事件对象
在Flex中,事件表现为事件对象。所有的事件对象必须直接,或者间接继承flash.events.Event类。事件对象有两个主要用途,可以代表的事件的属性;可用于影响事件处理系统的行为。Event类已经定义了一些必要的属性和方法,本节主要介绍Event类的构造方法、属性,然后介绍Event类方法,最后说明Event类的子类。
? 第十一、Event类的构造函数
无论使用Event类创建事件对象,还是继承Event类时,都要清楚的了解Event类的构造函数。
Event的构造函数如下所示。
public function Event(type:String, bubbles:Boolean = false,cancelable:Boolean = false)
参数说明:
type:事件的类型。例如鼠标单击的事件类型为MouseEvent.CLICK。事件的类型可以通过Event.type获得。
bubbles:该事件对象是否可以上浮。true表示可以上浮,false表示不可以上浮。默认为fasle。
cancelable:该事件是否可以被取消。true表示可以取消。fasle表示不可以取消。默认为false。
? 第十二、Event类属性
Event类定义多个公开的实例属性,用来存储事件的重要的信息。在事件发生时,这些属性可以提供有关事件对象的重要信息。
在ActionScript 2.0中,Event类中的type和target属性是可读且可写的。而在ActionScript 3.0中,Event类的实例属性全部为只读,避免在事件发生后,其原有的属性受到破坏、Event类的属性如表所示。Flex事件机制详细讲授
第十三、Event类方法
Event类中包含7个实例方法,可以分为如下3类:
实用程序方法:包含clone()、formatToString()、toString()。可以创建事件对象的副本或将其转换为字符串。
事件流方法:包含stopImmediatePropagation()和stopPropagation()用于阻止事件在事件流中进行传播。
默认行为方法:包含isDefaultPrevented()和preventDefault()可阻止默认行为或检查是否已阻止默认行为。
? 第十四、Event类的子类
对于很多事件,Event类中定义的一组公共属性已经足够了。但是,对以一些独特事件,例如鼠标事件、数据控件的条目点击事件等,Event类中可用的属性无法捕获这些事件的独特特性。这些事件在Flash Player API定义为Event类的子类。
每个子类提供了对于该事件来说唯一的属性和事件类型。例如,与鼠标输入相关的事件具有若干属性。MouseEvent类添加了10个属性。这些独特的特性,无法从Event类中定义的属性中获得。Event子类还包含代表与子类关联的事件类型的常量。例如,MouseEvent类定义几种鼠标事件类型的内容,包括click、doubleClick、mouseDown和mouseUp事件类型。
?第十五、事件发送
事件机制中最重要的2个部分,分别是上一节介绍的事件对象Event和本节要介绍的EventDispatcher,二者缺一不可。其中Event类及其子类的功能是提供各种具体的事件供EventDispatcher使用。EventDispatcher则是要让它所有的子类都能发送事件。
在Flex和ActionScript中所有要发送事件的类都继承于EventDispatcher。自定义事件发送事件主要有以下三种方式:
继承EventDispatcher类。
复合EventDispatcher对象。
利用IEventDispatcher接口实现。
下面将分别介绍这三种方式
? 1)继承EventDispatcher类
所有的可视对象都继承DisplayObject,利用其与EventDispatcher的继承关系,可以直接使用dispatchEvent()来发送事件。采用继承EventDispatcher进行事件发送是最方便最快的一种。
下面的例子采用了继承EventDispatcher类定义事件发送。自定义发送事件类定义在MyDispatcher中。
? 2)复合EventDispatcher对象。
什么情况下用复合EventDispatcher来发送Event呢?一般发生在某个较复杂的类里面。这个类可能是因为本身已经继承了其他类,无法再继承EventDispatcher。
如果仅仅是因为这个原因,那么建议使用实现IEventDispatcher接口来进行事件发送。如果希望这个类不是一个单纯事件发送类,而是在执行某个方法,如doSomething()时,附带的发送一些事件。这些事件发送往往是这个类的组成部分,那么用复合EventDispatcher实例来实现事件发送,这样的做法就比较合理。
只有在不能使用继承EventDispatcher和使用IEventDispatcher接口时,使用复合EventDispatcher才是比较合适的。
? 3)使用IEventDispatcher接口
由于ActionScript 3.0不支持继承多个类,在类已经继承其他类情况下,若要实现EventDispatcher类所有功能,只能通过IEventDispatcher接口实现事件发送。该方式看起来和和继承EventDispatcher区别不大。
使用IEventDispatcher接口发送方式具有如下两个优点:
类的用户完全感觉不到差别。
在被包装的方法中,还可以加入其他自己希望加进去的动作。
使用IEventDispatcher需要实现5个接口:addEventListener、hasListener、willTrigger、removeEventListener、hasEventListener。
十六、事件侦听器
在事件发生后,由事件侦听器接收事件的信息,处理事件。Flex 4.0中的事件侦听器是基于ActionScript 3.0来实现,在下面的介绍中我们主要讨论ActionScript 3.0事件侦听器。
十七、事件侦听器流程
在现实对象发出事件后,由事件侦听器处理事件。所以事件侦听分为2步,如下所示。
编写事件侦听器函数,该函数的类型必须时function。
使用addEventListener()为指定事件类型注册事件侦听器。
这里需要注意,显示对象必须是EventDsipatcher类的实例或者子类,否则事件侦听器无法接收事件及事件信息。在事件处理结束后,需要移除事件侦听器。
十八、创建侦听器函数
虽然Flex 2以及ActionScript 3.0基于DOM 3事件模型。但是在创建侦听器函数时,与DOM事件模型有一定的差异。
在DOM事件模型中,事件侦听器和侦听器函数之间有一个明显的不同:即事件侦听器是实现EventListener接口的类的实例,该实例的handleEvent()方法负责接收事件对象,即事件侦听器与事件处理函数是无法分开的。注册事件侦听器时是包含侦听器函数的类实例,而不是实际的侦听器函数。
在Flex 2和ActionScript 3.0事件模型中,事件侦听器和侦听器函数之间没有区别。侦听器函数可以在类外部定义,也可以定义为类的一部分。此外,无需将侦听器函数命名为handleEvent(),可以根据需要任意的命名。注册事件侦听器时,实际注册的是侦听器函数的名称。
十九、管理事件侦听器
在创建事件侦听器后,可以利用方法来管理事件侦听器,包括添加、移除、查询事件侦听器。下面对添加、移除、查询事件侦听器进行逐一介绍。
1.注册事件侦听器
注册事件侦听器时,使用EventDsipatcher类中的AddEventLsitener()方法即可。AddEventLsitener()的接口如下所示:
public function addEventListener(type:String, listener:Function,useCapture:Boolean = false, priority:int = 0,useWeakReference:Boolean = false):void
2.移除事件侦听器
在使用完事件侦听器后,应移除事件侦听器。移除事件侦听器使用removeEventListener()方法,该方法的接口如下所示。
public function removeEventListener(type:String, listener:Function,useCapture:Boolean = false):void
3.检测事件侦听器
在EventDsipatcher中,可以使用hasEventListener()和willTrigger()两个方法检测是否为某特定事件注册事件侦听器。这两个方法的接口如下所示。
function hasEventListener(type:String):Boolean;
functionwillTrigger(type:String):Boolean;

热点排行