Flash/Flex学习笔记(34):AS3中的自定义事件

类似C#中自定义事件需要一个自定义的EventArgs子类一样,AS3也需要开发者自定义一个Event类的子类,这里我们假设一种场景:设计一个Person(人物)类,里面有Age(年龄),Name(姓名),我们希望每当Person类的实例Age(年纪)发生变化时,能触发一些自定义事件,从而调用某些特定的处理方法。

1.先设计Event类的子类AgeChangeEvent

view source

print?

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类

view source

print?

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文件,在第一帧写入以下测试代码 :

view source

print?

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改造一下(注意新增部分):

view source

print?

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部分也要改一下:

view source

print?

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中的代码稍加改动:

view source

print?

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类

view source

print?

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类

view source

print?

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
}

测试程序:

view source

print?

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
}

posted @ 2010-11-22 17:14  模西的哥哥  阅读(537)  评论(0编辑  收藏  举报