- 論壇徽章:
- 0
|
轉(zhuǎn)載:http://www.ibm.com/developerworks/cn/web/1011_simq_flexlifecycle/index.html?ca=drs- 首先學(xué)習(xí)《FLEX組件生命周期1_原理》
1.關(guān)于 createChildren()方法 代碼1-1顯示了組件 ImageViewer 的 createChildren() 方法。 代碼1-1. ImageViewer 的 createChildren() 方法
- override protected function createChildren():void
-
{
-
trace('createChildren');
-
super.createChildren();
-
-
//創(chuàng)建邊框CSS
-
if(!this.border){
-
createBorder();
-
}
-
-
//創(chuàng)建控制按鈕容器
-
if (!controlBar)
-
controlBar = new UIComponent();
-
-
//創(chuàng)建放大按鈕
-
if (!zoomInButton){
-
zoomInButton = new Button();
-
zoomInButton.label = "+";
-
zoomInButton.addEventListener(MouseEvent.CLICK, zoomInButtonClickHandler);
-
controlBar.addChild(zoomInButton);
-
}
-
-
//創(chuàng)建縮小按鈕
-
if (!zoomOutButton){
-
zoomOutButton = new Button();
-
zoomOutButton.label = "-";
-
zoomOutButton.addEventListener(MouseEvent.CLICK, zoomOutButtonClickHandler);
-
controlBar.addChild(zoomOutButton);
-
}
-
-
// 將控制按鈕容器添加到顯示節(jié)點(diǎn)
-
addChild(controlBar);
-
}
在該方法的末尾才把controlBar 添加到 Display List 上,正如之前提到的那樣,我們只在需要的時(shí)候裝配他。同時(shí),此時(shí)也是為子節(jié)點(diǎn)添加監(jiān)聽(tīng)器的好地方。
2.關(guān)于 commitProperties()方法 CommitProperties()是驗(yàn)證方法 invalidateProperties()所對(duì)應(yīng)的提交方法,也是初始化階段會(huì)被調(diào)用的第一個(gè)提交方法。他的目的是使得任何通過(guò) set 方法提交的數(shù)值更改生效。所以您可以看到在 set scale()方法里,按照 invalidation-validation 模式,我們調(diào)用了 invalidateProperties()方法從而將值的生效延遲到了 commitProperties()里,并且為了做到 “避免對(duì)一個(gè)屬性連續(xù)設(shè)置多個(gè)值,從而避免了不必要的資源浪費(fèi)”,我們使用了標(biāo)志位 scaleChanged。
代碼2-1 set scale()函數(shù)
- public function set scale(value : Number):void{
-
if (_scale != value)
-
{
-
_scale = value;
-
-
//避免對(duì)一個(gè)屬性連續(xù)設(shè)置多個(gè)值,從而避免了不必要的資源浪費(fèi)
-
scaleChanged = true;
-
-
//由于調(diào)用本方法時(shí),可能對(duì)象未創(chuàng)建
-
//通過(guò)調(diào)用invalidateProperties(),將值的生效延遲到了commitProperties()里
-
invalidateProperties();
-
dispatchEvent(new Event("scaleChanged"));
-
}
-
}
代碼2-2 commitProperties()函數(shù)
- override protected function commitProperties():void{
-
trace('commitProperties');
-
super.commitProperties();
-
-
//如果image控件不存在,則新建并添加
-
if (sourceChanged){
-
if(!this.image){
-
image = new Image();
-
this.addChild(image);
-
image.source = this._source;
-
}else{
-
image.source = this._source;
-
}
-
sourceChanged = false;
-
}
-
-
//如果scale屬性改變了,則修改imageWidth
-
if(scaleChanged){
-
this.imageWidth = this.imageWidth * this.scale;
-
this.imageHeight = this.imageHeight * this.scale;
-
scaleChanged = false;
-
}
-
}
為什么在 commitProperties()會(huì)有添加子節(jié)點(diǎn)的操作呢? 對(duì)于有些子節(jié)點(diǎn),他的誕生可能是和某些屬性值相關(guān)聯(lián)的,也就是我們?cè)谥疤岬降膭?dòng)態(tài)創(chuàng)建或者數(shù)據(jù)驅(qū)動(dòng)的子節(jié)點(diǎn)。這些子節(jié)點(diǎn),由于他們并不是隨著組件的產(chǎn)生而產(chǎn)生,而是要受屬性值的變化而產(chǎn)生或者變化,甚至在某些情況下,根本就不需要存在。所以我們應(yīng)該在值的提交階段,也就是 commitProperties()方法調(diào)用的時(shí)候,當(dāng)新值真正生效的時(shí)候再去創(chuàng)建它。
3.關(guān)于 measure() 方法 measure()方法是組件自動(dòng)計(jì)算尺寸大小的地方,在例子 ImageViewer 的 measure()方法里(如代碼3-1 所示).如果已經(jīng)指定了尺寸大小,即 width 和 height 值,measure()方法不會(huì)被調(diào)用。所以一旦您的組件在組裝階段被設(shè)置了 with 和 height 屬性值,那么請(qǐng)不要期望在 measure 里會(huì)執(zhí)行您的業(yè)務(wù)邏輯。 代碼3-1 measure()函數(shù)
- override protected function measure():void{
-
trace('measure ');
-
super.measure();
-
if(!image){
-
//如果image控件不存在,則本組件的寬度為controlBar的寬度
-
measuredWidth = controlBar.getExplicitOrMeasuredWidth();
-
measuredHeight = controlBar.getExplicitOrMeasuredHeight();
-
}else{
-
//如果image控件存在,則本組件的寬度為controlBar的寬度
-
measuredWidth = image.width + Math.max(image.width, controlBar.getExplicitOrMeasuredWidth()) ;
-
measuredHeight = image.height + controlBar.getExplicitOrMeasuredHeight();
-
}
-
measuredMinWidth = measuredWidth;
-
measuredMinHeight = measuredHeight;
-
}
4.關(guān)于 updateDisplayList ()方法 updateDisplayList()方法用于對(duì)組件內(nèi)容進(jìn)行布局以及渲染,一切屏幕上可見(jiàn)的內(nèi)容都需要在這里被處理,所以 updateDisplayList()可以說(shuō)是最繁忙的一個(gè)提交方法,他所包含的實(shí)現(xiàn)可以非常多。代碼4-1中,我們省略了部分代碼。只留下了需要講解的部分。
代碼4-1 updateDisplayList()函數(shù)部分代碼
- override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number): void {
-
super.updateDisplayList(unscaledWidth, unscaledHeight);
-
// 省略部分代碼
-
zoomInButton.setActualSize(50, 20);
-
zoomOutButton.setActualSize(50, 20);
-
var tmpx : Number = 20;
-
controlBar.setActualSize(tmpx, 20);
-
controlBar.move(0, unscaledHeight-25);
-
zoomInButton.move(tmpx, 0);
-
tmpx +=60;
-
zoomOutButton.move(tmpx, 0);
-
if (imageHeightChanged ||imageWidthChanged){
-
image.width = this.imageWidth;//w;
-
image.height = this.imageHeight;//h - 20;
-
var tempX : Number = x+ (w-imageWidth) * 0.5;
-
var tempY : Number = y + (h-imageHeight) * 0.5;
-
image.x = tempX;
-
image.y = tempY;
-
imageHeightChanged = false ;
-
imageWidthChanged = false ;
-
var g:Graphics = graphics;
-
g.clear();
-
g.beginFill(0x6F7777);
-
g.drawRect(tempX-1, tempY-1, imageWidth+2, imageHeight+2);
-
g.endFill();
-
}
-
}
在 measure()方法里我們可以獲取 Flex 自動(dòng)計(jì)算的尺寸(如果被調(diào)用的話),這些數(shù)據(jù)需要在 updateDisplayList() 方法里被應(yīng)用處理,所以我們會(huì)大量使用 setActualSize()方法,特別是子元素比較多的時(shí)候。 updateDisplayList()的最重要的職責(zé)之一就相對(duì)應(yīng)的 invalidateDisplayList()方法的更新請(qǐng)求進(jìn)行響應(yīng)。比如說(shuō)對(duì)set imageWidth()方法進(jìn)行了相應(yīng)。并且就像在 commitProperties()部分里介紹的那樣,這里同樣使用了“標(biāo)志位”方法來(lái)進(jìn)行“局部跟新”。
局部更新是普遍應(yīng)用于提交方法里的一種技巧,因?yàn)槲覀冎肋@三個(gè)提交方法是公用的,任何更新的提交都會(huì)在這幾個(gè)方法里被處理。而每次更新都可能只是局部的更改,所以是當(dāng)?shù)厥褂脴?biāo)志位方法進(jìn)行局部更新可以有效地優(yōu)化代碼的執(zhí)行。
渲染屏幕的職責(zé)也決定了 updateDisplayList()方法是調(diào)用 Flash Player 繪圖 API 的好地方。所以我們?cè)诖a4-1 中特意使用了 drawRect()方法為圖片家了一個(gè)邊框。
參考文獻(xiàn) 1.http://www.ibm.com/developerworks/cn/web/1011_simq_flexlifecycle/index.html?ca=drs-
|
|