使用flex也很久了,也改过别人写的flex自定义组件,但是就是没有系统的研究下flex组件的编写步骤,和要注意的东西,在这里我参照一本书中的例子,好好的理解下,也为了巩固下自己对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);
}
}
}
原文:http://www.cnblogs.com/wshsdlau/p/3627807.html