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);
}
}
}