自定义事件和自定义事件类

正确区分自定义事件和自定义事件类,如果你只是简单地发送一个你自己的事件而不需要更多信息,可以使用

 

var myInfo:Event = new  Event( " myOwnEvent " );
dispatchEvent(myInfo)

 

来实现, 我们看到自定义事件很简单,只需给Event类传入一个特殊的不与内置事件类型重复的字符串即可
    可以做如下测试:
代码
// outer
var outer  =   new  Sprite();
outer.name
= " Outer " ;
outer.graphics.beginFill(
0xFF0000 );
outer.graphics.drawRect(
0 , 0 , 100 , 100 );
// mid
var mid  =   new  Sprite();
mid.name
= " mid "
mid.graphics.beginFill(
0x00FF00 );
mid.graphics.drawRect(
0 , 0 , 50 , 50 );
// inner
var inner  =   new  Sprite();
inner.name
= " inner " ;
inner.graphics.beginFill(
0x0000FF );
inner.graphics.drawRect(
0 , 0 , 25 , 25 );
// addChild
outer.addChild(mid);
mid.addChild(inner);
addChild(outer);
outer.x
= outer.y = 100 ;
// 添加侦听器
outer.addEventListener( " myOwnEvent " ,myOwnEventHandler, true ); // 注意此处将useCapture设为true所以会在捕获阶段调用侦听器
mid.addEventListener( " myOwnEvent " ,myOwnEventHandler, true ); // 同上
inner.addEventListener( " myOwnEvent " ,myOwnEventHandler);
function myOwnEventHandler(evt){
        trace(
" 事件流当前阶段: " + evt.eventPhase)
        trace(
" 鼠标点击处最内层的显示对象(target)是: "   +  evt.target.name)
        trace(
" 事件当前流经显示对象(currentTarget)是: " + evt.currentTarget.name)
        trace(
" =============================================================== " )
   
}
var myInfo
= new  Event( " myOwnEvent " )
inner.dispatchEvent(myInfo)
// 由inner向FlashPlayer提出请求把一个myOwnEvent的事件对象加入事件流

 

 

输出
事件流当前阶段:1
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:Outer
===============================================================
事件流当前阶段:1
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:mid
===============================================================
事件流当前阶段:2
鼠标点击处最内层的显示对象(target)是:inner
事件当前流经显示对象(currentTarget)是:inner
===============================================================
可以看到我们自定义的事件被加入到了事件流中并且被outer,mid,inner收到了
这里要补充一点, dispatchEvnet的调用对象将会被作为事件的目标对象(target)
晕了没?
你可以修改一下上面的代码来帮助你理解
代码:
var myInfo = new  Event( " myOwnEvent " )
trace(myInfo.target)
// 输出调用dispatchEvent方法前的target的名字,输出结果是null
inner.dispatchEvent(myInfo)
trace(myInfo.target.name)
// 输出调用dispatchEvent方法前的target的名字,输出结果是inner

 

 

如果你认真看完了上面的文字,你应该对自定义事件有了一定了解,在一般情况下,这种方法已经够用了,如果你还需要更复杂的事件的话,你就可以考虑创建你自己的 事件类

编写自己的事件类
   在上面的Mp3播放器例子中我们提到了给Mp3播放控制部分发送一个ProgressChangeEvent事件,现在继续
   给它发送这个事件的目标是要让它知道播放进度改变了,还要让它知道进度变成了多少,这就是参数progressBar.progress的作用
自定义事件类
代码
package
{
    
import  flash.events.Event;
    
    
public   class  ProgressChangeEvent  extends  Event
    {
        
static   private   const  PROGRESS_CHANGE  =   " progresschange " // 是不是跟MouseEvent.MOUSE_DOWN长得很像,其实MouseEvent差不多也是这么写出来的
         public  var position:Number  =   0 // 这是我们新加的变量,用来存储进度信息。

        
public  function ProgressChangeEvent(pos:Numbre)
        {
            
super (PROGRESS_CHANGE);  // 调用父类的构造函数,将PROGRESS_CHANGE设置为默认事件类型
            position  =  pos;
        }

        
public  override function clone():Event  // 你应负责任地重写clone方法
        {
            var cloneEvent 
=   new  ProgressEvent();
            cloneEvent.position 
=   this .position;
            
return  cloneEvent;
        }

        
public  override function toString():String  // 你应负责任地重写toStrin方法
        {
            
return  formatToString( " ProgressChangeEvent " " type " " bubbles " " cancelable " " eventPhase " " position " );
        }

    }

}

 

 

一个修秀的程序员应该在自定义类中重写clone和toString方法,不论你是否会用到这两个方法!!因为在调用dispatchEvent(myInfo)时实际是把myInfo对象的一个拷贝给了dispatchEvent方法。
-_-!!终于写完了,现在我们可以使用自己写的事件类了。
把上面的代码保存成ProgressChangeEvent.as文件,然后在同一目录下新建一个fla文件F9打开动作面板输入:

代码:

代码
import  ProgressChangeEvent // 其实可以省略,因为在同一目录下

// PlayerContralCenter
var PlayerContralCenter = new  Sprite();
PlayerContralCenter.name
= " PlayerContralCenter "
PlayerContralCenter.graphics.beginFill(
0x00FF00 );
PlayerContralCenter.graphics.drawRect(
0 , 0 , 100 , 100 );
// progressBar
var progressBar = new  Sprite();
progressBar.name
= " progressBar "
progressBar.graphics.beginFill(
0xFF0000 );
progressBar.graphics.drawRect(
0 , 0 , 100 , 5 );
// addChild
PlayerContralCenter.addChild(progressBar);
addChild(PlayerContralCenter);
progressBar.y
= 50
PlayerContralCenter.x
= PlayerContralCenter.y = 100

// PlayerContralCenter侦听ProgressChangeEvent事件,将useCapture设置为true的原因是我们的自定义事件类是不冒泡的(你也可以修改成可冒泡的),所以必须在捕获阶段响应
PlayerContralCenter.addEventListener(ProgressChangeEvent.PROGRESS_CHANGE,handler, true );
progressBar.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);


function handler(evt:ProgressChangeEvent){
    trace(
" 我是 " + evt.currentTarget.name + " ,我收到了 " + evt.type + " 事件, " + " 事件信息是 " + evt.position);
}
function mouseDownHandler(evt:MouseEvent){
        var pos
= evt.target.mouseX / evt.target.width;
    progressBar.dispatchEvent(
new  ProgressChangeEvent(pos));
}

 

 

输出
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.42
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.84
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.94
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.97
我是PlayerContralCenter,我收到了progresschange事件,事件信息是0.05
.............

你可能感兴趣的:(自定义)