zoukankan      html  css  js  c++  java
  • Flash/Flex学习笔记(34):AS3中的自定义事件

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

    1.先设计Event类的子类AgeChangeEvent

    package {
    
    	import flash.events.Event;
    
    	public class AgeChangeEvent extends Event {
    		
    		public static const AGE_OUT_OF_RANGE:String="AGE_OUT_OF_RANGE";
    		public static const AGE_CHANGE:String="AGE_CHANGE";
    		
    		public function AgeChangeEvent(eventType:String){
    			super(eventType);
    		}
    	}
    }
    

    这里我们定义了二类事件:年龄变化(AGE_CHANGE)、年龄超出范围(AGE_OUT_OF_RANGE)

    2.再来设计Person类

    package {
    
    	import flash.display.Sprite;
    	
    	public class Person extends Sprite {
    
    		private var _age:uint;
    
    		private var _personName:String;
    
    		public function Person(personName:String,age:uint) {
    			this._age=age;
    			this._personName=personName;
    		}
    		
    		//将_age封装成属性
    		public function get Age():uint{
    			return _age;
    		}
    		
    		//Age属性的setter方法(在这里加入事件派发处理)
    		public function set Age(age:uint):void{
    			
    			if (age!=this._age){
    				var _ageChangeEvent1:AgeChangeEvent = new AgeChangeEvent(AgeChangeEvent.AGE_CHANGE);				
    				dispatchEvent(_ageChangeEvent1);//触发Age改变事件
    			}
    			
    			if (age>=120){
    				var _ageChangeEvent2:AgeChangeEvent = new AgeChangeEvent(AgeChangeEvent.AGE_OUT_OF_RANGE);				
    				dispatchEvent(_ageChangeEvent2);//触发Age超过正常范围事件
    			}
    			
    			this._age = age;
    			
    		}		
    		
    		//覆盖父类的toString方法
    		public override function toString():String{
    			return "“" + this._personName + "”童鞋一晃今年都已经“" + this._age + "”岁了,真是岁月不饶人啊.";
    		}
    
    	}
    }
    

    注意这里的dispatchEvent处理部分,先定义一个事件(参数)对象,然后派发事件.(类似C#中的委托/事件机制,Person类并不知道最终Peson的使用者将如何处理这二个事件,但只要遵守约定就能正确调用开发者执行的处理方法)

    3.测试刚才的事件,新建一个Flash File(ActionScript3.0)的fla文件,在第一帧写入以下测试代码 :

    var jimmy:Person = new Person("菩提树下的杨过",30);
    trace(jimmy.toString());
    
    jimmy.Age = 31;//现在还没注册任何事件,所以啥也不会触发
    
    //注册事件
    jimmy.addEventListener(AgeChangeEvent.AGE_CHANGE,AgeChangeHandler);
    
    function AgeChangeHandler(e:AgeChangeEvent):void{
    	trace("注意:这家伙年龄改了!");
    }
    
    jimmy.Age = 32; //现在改变年龄时,将触发AgeChangeHandler事件
    
    jimmy.Age = 150; //将再次触发AgeChangeHandler事件
    
    //再注册一个事件
    jimmy.addEventListener(AgeChangeEvent.AGE_OUT_OF_RANGE,AgeOutOfRangeHandler);
    
    function AgeOutOfRangeHandler(e:AgeChangeEvent):void{
    	trace("注意:这老家伙居然说自己年龄超过120岁了!");
    }
    
    jimmy.Age = 149;//将同时触发AGE_CHANGE与AGE_OUT_OF_RANGE事件
    
    

    建议大家先猜猜结果,动手实践一下,再看下面的输出结果:

    “菩提树下的杨过”童鞋一晃今年都已经“30”岁了,真是岁月不饶人啊.
    注意:这家伙年龄改了!
    注意:这家伙年龄改了!
    注意:这家伙年龄改了!
    注意:这老家伙居然说自己年龄超过120岁了!

    有时候,我们还希望AgeChangeEvent参数还能附带一些额外信息,这个也难不倒AS,把AgeChangeEvent改造一下(注意新增部分):

    package {
    
    	import flash.events.Event;
    
    	public class AgeChangeEvent extends Event {
    		
    		public static const AGE_OUT_OF_RANGE:String="AGE_OUT_OF_RANGE";
    		public static const AGE_CHANGE:String="AGE_CHANGE";
    		
    		//新增部分
    		private var _OldAge:uint,_NewAge:uint;
    		
    		public function AgeChangeEvent(eventType:String,oldAge:uint,newAge:uint){
    			this._OldAge = oldAge;
    			this._NewAge = newAge;
    			super(eventType);
    		}
    		
    		public function get OldAge():uint{
    			return _OldAge;
    		}
    		
    		public function get NewAge():uint{
    			return _NewAge;
    		}
    	}
    }
    

    Person类里Age的setter部分也要改一下:

    //Age属性的setter方法(在这里加入事件派发处理)
    		public function set Age(age:uint):void{
    			
    			if (age!=this._age){
    				var _ageChangeEvent1:AgeChangeEvent = new AgeChangeEvent(AgeChangeEvent.AGE_CHANGE,this._age,age);				
    				dispatchEvent(_ageChangeEvent1);//触发Age改变事件
    			}
    			
    			if (age>=120){
    				var _ageChangeEvent2:AgeChangeEvent = new AgeChangeEvent(AgeChangeEvent.AGE_OUT_OF_RANGE,this._age,age);				
    				dispatchEvent(_ageChangeEvent2);//触发Age超过正常范围事件
    			}
    			
    			this._age = age;
    			
    		}		
    

    测试fla中的代码稍加改动:

    var jimmy:Person = new Person("菩提树下的杨过",30);
    trace(jimmy.toString());
    
    jimmy.Age = 31;//现在还没注册任何事件,所以啥也不会触发
    
    //注册事件
    jimmy.addEventListener(AgeChangeEvent.AGE_CHANGE,AgeChangeHandler);
    
    function AgeChangeHandler(e:AgeChangeEvent):void{
    	trace("注意:这家伙年龄从" + e.OldAge +"改成" + e.NewAge + "了!");
    }
    
    jimmy.Age = 32; //现在改变年龄时,将触发AgeChangeHandler事件
    
    jimmy.Age = 150; //将再次触发AgeChangeHandler事件
    
    //再注册一个事件
    jimmy.addEventListener(AgeChangeEvent.AGE_OUT_OF_RANGE,AgeOutOfRangeHandler);
    
    function AgeOutOfRangeHandler(e:AgeChangeEvent):void{
    	trace("注意:这老家伙居然说自己年龄超过120岁,现在已经有" + e.NewAge + "了!");
    }
    
    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类

    using System;
    
    namespace EventDemo
    {
        public class AgeChangeEventArgs:EventArgs
        {
            private uint _oldAge;
            private uint _newAge;
    
            public AgeChangeEventArgs(uint oldAge, uint newAge) 
            {
                this._oldAge = oldAge;
                this._newAge = newAge;
            }
    
            public uint OldAge { get { return _oldAge; } }
    
            public uint NewAge { get { return _newAge; } }
        }
    }
    
    

    Person类

    namespace EventDemo
    {
        public class Person
        {
            public delegate void AgeChangeEventHandler(object sender, AgeChangeEventArgs e);
    
            public event AgeChangeEventHandler AgeChangeEvent;
            public event AgeChangeEventHandler AgeOutOfRangeEvent;
    
            private uint _age;
            private string _name;
    
            public uint Age
            {
                get { return Age; }
                set
                {
                    if (value != _age)
                    {
                        if (AgeChangeEvent != null)
                        {
                            AgeChangeEvent(this, new AgeChangeEventArgs(_age, value));
                        }
                    }
    
                    if (value >= 120)
                    {
                        if (AgeOutOfRangeEvent != null)
                        {
                            AgeOutOfRangeEvent(this, new AgeChangeEventArgs(_age, value));
                        }
                    }
    
                    _age = value;
                }
            }
    
            public string Name
            {
                get { return _name; }
                set
                {
    
                    _name = value;
                }
            }
    
            public Person(string pName, uint pAge)
            {
                this._age = pAge;
                this._name = pName;
            }
    
            public override string ToString()
            {
                return "“" + this._name + "”今年已经“" + this._age + "”岁了!";
            }
        }
    }
    

    测试程序:

    using System;
    
    namespace EventDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                Person p = new Person("菩提树下的杨过", 30);
    
                Console.WriteLine(p.ToString());
    
                p.Age = 31;
    
                p.AgeChangeEvent += new Person.AgeChangeEventHandler(p_AgeChangeEvent);
    
                p.Age = 32;
    
                p.AgeOutOfRangeEvent += new Person.AgeChangeEventHandler(p_AgeOutOfRangeEvent);
    
                p.Age = 150;
    
                Console.ReadKey();
            }
    
            static void p_AgeOutOfRangeEvent(object sender, AgeChangeEventArgs e)
            {
                Console.WriteLine("天啊,这家伙的年龄居然已经达到" + e.NewAge + "岁了!");
            }
    
            static void p_AgeChangeEvent(object sender, AgeChangeEventArgs e)
            {
                Console.WriteLine("注意:这家伙的年龄从" + e.OldAge + "岁改成了" + e.NewAge + "岁!");
            }
        }
    }
    
    
    
    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    poj1459(多源点网络流)
    poj 2480
    poj1850和poj1496(组合数)
    poj3252(组合数)
    hdu1452(逆元)
    因子和与因子个数
    poj 2478(欧拉函数打表)
    p3807(lucas定理)
    F-有趣的数字(组合数+逆元)
    《Java并发编程的艺术》Java并发机制的底层实现原理(二)
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1712155.html
Copyright © 2011-2022 走看看