Flash/Flex学习笔记(34):AS3中的自定义事件
时间:2010-11-22 来源:模西的哥哥
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值控制,对象大小控制...),只要定义自己的处理函数,然后注册到该事件即可
源代码:http://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
}