Flash/Flex学习笔记(34):AS3中的自定义事件
类似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 }
浙公网安备 33010602011771号