flex自定義組件的編寫步驟

 1,重寫一個組件系統依次調用Constructor(構造方法)-->createChildren()-->commitProperties()==>measure()==>updateDisplayList() ;
    a,Constructor構造方法,初始化屬性,默認值 在這個方法中使用最好。
    b,createChildren() 創建子對象,在組件中添加子對象。是使用addChild方法添加子對象
    c,commitProperties 用在處理屬性值和更新。(多個屬性值更新後統一處理入口和單值多次修改後處理入口)
    d , measure()設置組件的默認大小(以便Flex佈局管理器能正確知道該組件的大小,給其分配適當空間)
    e,updateDisplayList()用來重繪組件,子對象佈局邏輯等

2,添加自定義組件實際上就是將一個基本的組件的組合起來,這樣的情況下就必須要重寫createChildren() 和 updateDisplayList()方法。
    當自定義組件要對屬性的變化作出反應的時候必須要重寫commitProperties()方法(觸發調用這個方法的是invalidateProperties) 
    當自定義的組件和基類組件大小不一致的情況下就要調用measure 保證正確的大小顯示。(調用invalidateSize方法)
    當組件需要調整子對象全局顯示邏輯,重寫updateDisplayList,調用invalidateDisplayList

    commitProperties   measure 和 updateDisplayList 都有自己的用處

    在下面寫個例子 一個button 和 TextArea 組合的自定義組件

package cn.tsoft
{
	import flash.events.Event;
	import flash.text.TextLineMetrics;
	
	import mx.controls.Button;
	import mx.controls.TextArea;
	import mx.core.UIComponent;
	
	
	
	/**
	 * 當子組件textArea中文件變化時,ModelText派發一個change事件
	 * 當ModelText的text屬性被設置時,派發一個textChange事件
	 * 當改變Modeltext的textplacement屬性後,會派發一個placementChanged事件 
	 * **/
	[Event(name="change",type="flash.events.Event")]
	[Event(name="textChanged",type="flash.events.Event")]
	[Event(name="placementChanged",type="flash.events.Event")]
	
	public class ModelText extends UIComponent
	{
		public function ModelText()
		{
			super();
		}
		
		private var text_mc:TextArea;
		private var mode_mc:Button;
		
		
		private var bTextChanged:Boolean =false;
		
		private var _text:String="ModelText";
		
		
		public function set text(t:String):void{
			this._text =t;
			bTextChanged = true;
			invalidateProperties();
			dispatchEvent(new Event("textChanged"));
		}
		
		
		[Bindable(event="textChanged")]
		public function get text():String{
			return text_mc.text;
		}
		
		
		override protected function createChildren():void{
			super.createChildren();
			if(!text_mc){
				text_mc =new TextArea();
				text_mc.explicitWidth =80;
				text_mc.editable =false;
				text_mc.addEventListener("change",handleChangeEvent);
				addChild(text_mc);
			}
			
			if(!mode_mc){
				mode_mc = new Button();
				mode_mc.label ="mylabeljieji";
				mode_mc.addEventListener("click",handleClickEvent);
				addChild(mode_mc);
			}
		}
		
		
		//處理有子組件派發的時間
		private function handleChangeEvent(eventObj:Event):void{
			dispatchEvent(new Event("change"));
		}
		
		private function handleClickEvent(eventObj:Event):void{
			text_mc.editable = !text_mc.editable;
		}
		
		
		override protected function commitProperties():void{
			super.commitProperties();
			if(bTextChanged){
				bTextChanged =false;
				text_mc.text = _text;
				invalidateDisplayList();
			}
		}
		
		/**
		 * 組建的默認寬度是文本寬度加上按鈕的寬度
		 * 組件的默認高度由按鈕的高度決定
		 */ 
		override protected function measure():void{
			super.measure();
			var buttonWidth:Number = mode_mc.getExplicitOrMeasuredWidth();
			var buttonHeight:Number =mode_mc.getExplicitOrMeasuredHeight();
			
			//組件默認的最小寬度和默認寬度爲textArea控件的measureedWidth寬度與buttonWidth之和
			measuredWidth = measuredMinWidth =text_mc.measuredWidth+buttonWidth;
		//組件的默認高度 和最小高度問textArea 和Button 中measuredHeight中的最大值加上10個像素的邊框
		    measuredHeight = measuredMinHeight = Math.max(text_mc.measuredHeight,buttonHeight)+10;
		}
		
		
		private var _textPlacement:String="left";
		
		public function set textPlacement(p:String):void{
			this._textPlacement = p;
			invalidateDisplayList();
			dispatchEvent(new Event("placementChanged"));
		}
		
		[Bindable(event="placementChanged")]
		public function get textPlacement():String{
			return _textPlacement;
		}
		
		
		/**
		 * Button控件的尺寸是Button上的label文本尺寸加上10像素的邊框區域
		 * textarea控件的尺寸是組件的剩餘區域,TextArea的位置取決於textPlacement屬性的設置
		 * **/
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
			super.updateDisplayList(unscaledWidth,unscaledHeight);
			//爲左右邊框各減去1像素 , 爲左右邊白各減3像素
			var usableWidth:Number=unscaledWidth -8;
			//爲上下邊框各減去1像素 , 爲上下邊白各減3像素
			var usableHeight:Number = unscaledHeight -8;
			
			//根據按鈕上的文本計算按鈕的尺寸
			var lineMetrics:TextLineMetrics = measureText(mode_mc.label);
			//按鈕文本尺寸加上10像素作爲按鈕的尺寸
			var buttonHeight:Number = lineMetrics.height+10;
			var buttonWidth:Number = lineMetrics.width+10;
			mode_mc.setActualSize(buttonWidth,buttonHeight);
			
			//計算文本的尺寸,允許按鈕和TextArea文本之間有5個像素的間隙
			var textWidth:Number = usableWidth-buttonWidth-5;
			var textHeight:Number = usableHeight;
			text_mc.setActualSize(textWidth,textHeight);
			
			//根據textPlacement的屬性確定控件的位置
			if(textPlacement == "left"){
				text_mc.move(4,4);
				mode_mc.move(4+textWidth+5,4);
			}else{
				mode_mc.move(4,4);
				text_mc.move(4+buttonWidth+5,4);
			}
			
			graphics.lineStyle(1,0xffff00,1.0);
			graphics.drawRect(0,0,unscaledWidth,unscaledHeight);
		}
		
		

	}
}




 

發佈了37 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章