类似C#中自定义事件需要一个自定义的EventArgs子类一样,AS3也需要开发者自定义一个Event类的子类,这里我们假设一种场景:设计一个Person(人物)类,里面有Age(年龄),Name(姓名),我们希望每当Person类的实例Age(年纪)发生变化时,能触发一些自定义事件,从而调用某些特定的处理方法。
1.先设计Event类的子类AgeChangeEvent
01
package
{
02
03
import
flash.events.Event;
04
05
public
class
AgeChangeEvent
extends
Event {
06
07
public
static
const
AGE_OUT_OF_RANGE:
String
=
"AGE_OUT_OF_RANGE"
;
08
public
static
const
AGE_CHANGE:
String
=
"AGE_CHANGE"
;
09
10
public
function
AgeChangeEvent(eventType:
String
){
11
super
(eventType);
12
}
13
}
14
}
这里我们定义了二类事件:年龄变化(AGE_CHANGE)、年龄超出范围(AGE_OUT_OF_RANGE)
2.再来设计Person类
01
package
{
02
03
import
flash.display.Sprite;
04
05
public
class
Person
extends
Sprite {
06
07
private
var
_age:
uint
;
08
09
private
var
_personName:
String
;
10
11
public
function
Person(personName:
String
,age:
uint
) {
12
this
._age=age;
13
this
._personName=personName;
14
}
15
16
//将_age封装成属性
17
public
function
get
Age():
uint
{
18
return
_age;
19
}
20
21
//Age属性的setter方法(在这里加入事件派发处理)
22
public
function
set
Age(age:
uint
):
void
{
23
24
if
(age!=
this
._age){
25
var
_ageChangeEvent1:AgeChangeEvent =
new
AgeChangeEvent(AgeChangeEvent.AGE_CHANGE);
26
dispatchEvent(_ageChangeEvent1);
//触发Age改变事件
27
}
28
29
if
(age>=
120
){
30
var
_ageChangeEvent2:AgeChangeEvent =
new
AgeChangeEvent(AgeChangeEvent.AGE_OUT_OF_RANGE);
31
dispatchEvent(_ageChangeEvent2);
//触发Age超过正常范围事件
32
}
33
34
this
._age = age;
35
36
}
37
38
//覆盖父类的toString方法
39
public
override
function
toString():
String
{
40
return
"“"
+
this
._personName +
"”童鞋一晃今年都已经“"
+
this
._age +
"”岁了,真是岁月不饶人啊."
;
41
}
42
43
}
44
}
注意这里的dispatchEvent处理部分,先定义一个事件(参数)对象,然后派发事件.(类似C#中的委托/事件机制,Person类并不知道最终Peson的使用者将如何处理这二个事件,但只要遵守约定就能正确调用开发者执行的处理方法)
3.测试刚才的事件,新建一个Flash File(ActionScript3.0)的fla文件,在第一帧写入以下测试代码 :
01
var
jimmy:Person =
new
Person(
"菩提树下的杨过"
,
30
);
02
trace
(jimmy.toString());
03
04
jimmy.Age =
31
;
//现在还没注册任何事件,所以啥也不会触发
05
06
//注册事件
07
jimmy.addEventListener(AgeChangeEvent.AGE_CHANGE,AgeChangeHandler);
08
09
function
AgeChangeHandler(e:AgeChangeEvent):
void
{
10
trace
(
"注意:这家伙年龄改了!"
);
11
}
12
13
jimmy.Age =
32
;
//现在改变年龄时,将触发AgeChangeHandler事件
14
15
jimmy.Age =
150
;
//将再次触发AgeChangeHandler事件
16
17
//再注册一个事件
18
jimmy.addEventListener(AgeChangeEvent.AGE_OUT_OF_RANGE,AgeOutOfRangeHandler);
19
20
function
AgeOutOfRangeHandler(e:AgeChangeEvent):
void
{
21
trace
(
"注意:这老家伙居然说自己年龄超过120岁了!"
);
22
}
23
24
jimmy.Age =
149
;
//将同时触发AGE_CHANGE与AGE_OUT_OF_RANGE事件
建议大家先猜猜结果,动手实践一下,再看下面的输出结果:
“菩提树下的杨过”童鞋一晃今年都已经“30”岁了,真是岁月不饶人啊.
注意:这家伙年龄改了!
注意:这家伙年龄改了!
注意:这家伙年龄改了!
注意:这老家伙居然说自己年龄超过120岁了!
有时候,我们还希望AgeChangeEvent参数还能附带一些额外信息,这个也难不倒AS,把AgeChangeEvent改造一下(注意新增部分):
01
package
{
02
03
import
flash.events.Event;
04
05
public
class
AgeChangeEvent
extends
Event {
06
07
public
static
const
AGE_OUT_OF_RANGE:
String
=
"AGE_OUT_OF_RANGE"
;
08
public
static
const
AGE_CHANGE:
String
=
"AGE_CHANGE"
;
09
10
//新增部分
11
private
var
_OldAge:
uint
,_NewAge:
uint
;
12
13
public
function
AgeChangeEvent(eventType:
String
,oldAge:
uint
,newAge:
uint
){
14
this
._OldAge = oldAge;
15
this
._NewAge = newAge;
16
super
(eventType);
17
}
18
19
public
function
get
OldAge():
uint
{
20
return
_OldAge;
21
}
22
23
public
function
get
NewAge():
uint
{
24
return
_NewAge;
25
}
26
}
27
}
Person类里Age的setter部分也要改一下:
01
//Age属性的setter方法(在这里加入事件派发处理)
02
public
function
set
Age(age:
uint
):
void
{
03
04
if
(age!=
this
._age){
05
var
_ageChangeEvent1:AgeChangeEvent =
new
AgeChangeEvent(AgeChangeEvent.AGE_CHANGE,
this
._age,age);
06
dispatchEvent(_ageChangeEvent1);
//触发Age改变事件
07
}
08
09
if
(age>=
120
){
10
var
_ageChangeEvent2:AgeChangeEvent =
new
AgeChangeEvent(AgeChangeEvent.AGE_OUT_OF_RANGE,
this
._age,age);
11
dispatchEvent(_ageChangeEvent2);
//触发Age超过正常范围事件
12
}
13
14
this
._age = age;
15
16
}
测试fla中的代码稍加改动:
01
var
jimmy:Person =
new
Person(
"菩提树下的杨过"
,
30
);
02
trace
(jimmy.toString());
03
04
jimmy.Age =
31
;
//现在还没注册任何事件,所以啥也不会触发
05
06
//注册事件
07
jimmy.addEventListener(AgeChangeEvent.AGE_CHANGE,AgeChangeHandler);
08
09
function
AgeChangeHandler(e:AgeChangeEvent):
void
{
10
trace
(
"注意:这家伙年龄从"
+ e.OldAge +
"改成"
+ e.NewAge +
"了!"
);
11
}
12
13
jimmy.Age =
32
;
//现在改变年龄时,将触发AgeChangeHandler事件
14
15
jimmy.Age =
150
;
//将再次触发AgeChangeHandler事件
16
17
//再注册一个事件
18
jimmy.addEventListener(AgeChangeEvent.AGE_OUT_OF_RANGE,AgeOutOfRangeHandler);
19
20
function
AgeOutOfRangeHandler(e:AgeChangeEvent):
void
{
21
trace
(
"注意:这老家伙居然说自己年龄超过120岁,现在已经有"
+ e.NewAge +
"了!"
);
22
}
23
24
jimmy.Age =
149
;
//将同时触发AGE_CHANGE与AGE_OUT_OF_RANGE事件
新的输出结果:
“菩提树下的杨过”童鞋一晃今年都已经“30”岁了,真是岁月不饶人啊.
注意:这家伙年龄从31改成32了!
注意:这家伙年龄从32改成150了!
注意:这家伙年龄从150改成149了!
注意:这老家伙居然说自己年龄超过120岁,现在已经有149了!
后记:自定义事件可以广泛应用于很多场景,比如我们可以自己做一个控制滑块MovieClip,里面定义一个ValueChange事件,其它需要的地方(比如音量大小控制,对象Alpha值控制,对象大小控制...),只要定义自己的处理函数,然后注册到该事件即可
源代码:https://files.cnblogs.com/yjmyzz/as3_custom_events.rar
最后做为对比和复习,贴出C#版的自定义事件:
AgeChangeEventArgs类
01
using
System;
02
03
namespace
EventDemo
04
{
05
public
class
AgeChangeEventArgs:EventArgs
06
{
07
private
uint
_oldAge;
08
private
uint
_newAge;
09
10
public
AgeChangeEventArgs(
uint
oldAge,
uint
newAge)
11
{
12
this
._oldAge = oldAge;
13
this
._newAge = newAge;
14
}
15
16
public
uint
OldAge {
get
{
return
_oldAge; } }
17
18
public
uint
NewAge {
get
{
return
_newAge; } }
19
}
20
}
Person类
01
namespace
EventDemo
02
{
03
public
class
Person
04
{
05
public
delegate
void
AgeChangeEventHandler(
object
sender, AgeChangeEventArgs e);
06
07
public
event
AgeChangeEventHandler AgeChangeEvent;
08
public
event
AgeChangeEventHandler AgeOutOfRangeEvent;
09
10
private
uint
_age;
11
private
string
_name;
12
13
public
uint
Age
14
{
15
get
{
return
Age; }
16
set
17
{
18
if
(value != _age)
19
{
20
if
(AgeChangeEvent !=
null
)
21
{
22
AgeChangeEvent(
this
,
new
AgeChangeEventArgs(_age, value));
23
}
24
}
25
26
if
(value >= 120)
27
{
28
if
(AgeOutOfRangeEvent !=
null
)
29
{
30
AgeOutOfRangeEvent(
this
,
new
AgeChangeEventArgs(_age, value));
31
}
32
}
33
34
_age = value;
35
}
36
}
37
38
public
string
Name
39
{
40
get
{
return
_name; }
41
set
42
{
43
44
_name = value;
45
}
46
}
47
48
public
Person(
string
pName,
uint
pAge)
49
{
50
this
._age = pAge;
51
this
._name = pName;
52
}
53
54
public
override
string
ToString()
55
{
56
return
"“"
+
this
._name +
"”今年已经“"
+
this
._age +
"”岁了!"
;
57
}
58
}
59
}
测试程序:
01
using
System;
02
03
namespace
EventDemo
04
{
05
class
Program
06
{
07
static
void
Main(
string
[] args)
08
{
09
Person p =
new
Person(
"菩提树下的杨过"
, 30);
10
11
Console.WriteLine(p.ToString());
12
13
p.Age = 31;
14
15
p.AgeChangeEvent +=
new
Person.AgeChangeEventHandler(p_AgeChangeEvent);
16
17
p.Age = 32;
18
19
p.AgeOutOfRangeEvent +=
new
Person.AgeChangeEventHandler(p_AgeOutOfRangeEvent);
20
21
p.Age = 150;
22
23
Console.ReadKey();
24
}
25
26
static
void
p_AgeOutOfRangeEvent(
object
sender, AgeChangeEventArgs e)
27
{
28
Console.WriteLine(
"天啊,这家伙的年龄居然已经达到"
+ e.NewAge +
"岁了!"
);
29
}
30
31
static
void
p_AgeChangeEvent(
object
sender, AgeChangeEventArgs e)
32
{
33
Console.WriteLine(
"注意:这家伙的年龄从"
+ e.OldAge +
"岁改成了"
+ e.NewAge +
"岁!"
);
34
}
35
}
36
}