定義屬性
開發(fā)者通常希望"消息"能夠攜帶更多的信息,提供更多的數(shù)據(jù)。在自定義事件中,通過(guò)定義屬性,可以讓事件攜帶更多的信息。
編寫構(gòu)造器
類當(dāng)然離不開構(gòu)造器。事件類的構(gòu)造器要完成兩項(xiàng)任務(wù)。
(1). 調(diào)用Super()
通過(guò)Super()調(diào)用父類的構(gòu)造器,以初始化從父類繼承的屬性等。通常情況下,子類構(gòu)造器應(yīng)該首先調(diào)用Super()方法。當(dāng)然,如果沒(méi)有為子類編寫構(gòu)造器(不添加構(gòu)造器方法),編譯器會(huì)自動(dòng)添加一個(gè)構(gòu)造器,并且也會(huì)調(diào)用Super()。但是,我們?nèi)匀煌扑]編寫構(gòu)造器,并且顯式地調(diào)用Super()方法。
(2). 設(shè)置屬性
事件類型是最常用到的事件屬性。Super()可以接受String類型的參數(shù),由此設(shè)置父類事件中繼承來(lái)的事件類型屬性(event.type)。
除了事件類型外,事件的其他自定義屬性可以作為構(gòu)造器的參數(shù)傳入,在構(gòu)造器中完成初始化。更靈活的是,這些屬性類型不僅僅局限于String、Number等基本類型,還可以是任何自定義類。
重載clone方法
創(chuàng)建自定義事件的最后一步是重載父類的clone方法,返回新的Event對(duì)象。當(dāng)觸發(fā)事件時(shí),即dispatchEvent(event)時(shí),EventDispatcher會(huì)自動(dòng)調(diào)用clone方法獲取新的Event對(duì)象。
重載clone方法將復(fù)制自定義類的所有屬性。如果你沒(méi)有對(duì)自定義事件類中添加的所有屬性進(jìn)行賦值的話,那么當(dāng)偵聽器處理觸發(fā)的自定義事件時(shí),就不會(huì)獲得正確的屬性值。
2.使用元數(shù)據(jù)[Event]定義事件
通過(guò)[Event]元數(shù)據(jù),開發(fā)者可以為組件定義事件。編譯器能夠把這些自定義的事件識(shí)別為MXML標(biāo)簽屬性。使用[Event]既可以為ActionScript組件定義事件,也可以為MXML組件定義事件。
為ActionScript組件定義事件
為MXML組件定義事件
3.觸發(fā)事件
4.創(chuàng)建事件偵聽器
Flex的事件可以分為系統(tǒng)事件和用戶事件。
由用戶操作觸發(fā)的事件,就是用戶事件。Flex的用戶事件遵循了W3C DOM Level3(W3C文檔對(duì)象模型Level3)事件規(guī)范。具體可參見(jiàn)http://www.w3.org/TR/DOM-Level-3-Events/ 。用戶事件是應(yīng)用中最常見(jiàn)的事件類型,比如鼠標(biāo)點(diǎn)擊、鍵盤輸入等都屬于用戶事件。除了用戶直接觸發(fā)的事件,在Flex應(yīng)用運(yùn)行過(guò)程中,F(xiàn)lex架構(gòu)本身也會(huì)自動(dòng)觸發(fā)一些事件,也就是所謂的系統(tǒng)事件。在信號(hào)燈應(yīng)用中,creationComplete事件是系統(tǒng)事件,而MouseEvent.CLICK事件則是用戶事件。
所有的Flex可視化組件都繼承自基類mx.core.UIComponent,同時(shí)也繼承了UIComponent的系統(tǒng)事件。當(dāng)Flex應(yīng)用啟動(dòng)時(shí),會(huì)觸發(fā)一系列事件,這些事件表明了組件在啟動(dòng)過(guò)程中的不同時(shí)間點(diǎn),比如被創(chuàng)建、布局完成或者在屏幕上完成繪制等。這些啟動(dòng)序列事件幫助開發(fā)者更好的監(jiān)控并控制應(yīng)用運(yùn)行生命周期的各個(gè)環(huán)節(jié)。實(shí)際上,這"一系列"事件都由一個(gè)事件類mx.events. FlexEvent表示。FlexEvent類的不同類型反映了啟動(dòng)過(guò)程中不同階段發(fā)生的事件。
在Flex應(yīng)用中,容器和組件啟動(dòng)時(shí)的事件序列不同。
在組件所屬的容器內(nèi),組件被實(shí)例化、加入到父容器的顯示列表中,然后設(shè)置外觀尺寸,最終完成容器中的布局,并被繪制出來(lái)。圖3-1顯示了組件的啟動(dòng)事件序列:
由于容器包含了子組件,因此容器啟動(dòng)時(shí)的序列不同于單一組件,圖3-2顯示了包含子組件的容器的啟動(dòng)過(guò)程。不僅容器本身要完成創(chuàng)建的全過(guò)程,所包含的子組件也要依次序地完成自身的創(chuàng)建。當(dāng)然如果容器中嵌入了子容器,其啟動(dòng)過(guò)程與此類似。
圖3-2
Flex應(yīng)用啟動(dòng)的事件序列(2)
在所有組件和容器被創(chuàng)建并最終繪制在屏幕上之后,Application對(duì)象將觸發(fā)applicationComplete事件,該事件類型標(biāo)志著應(yīng)用啟動(dòng)完畢,是應(yīng)用啟動(dòng)時(shí)觸發(fā)的最后一個(gè)事件。
圖3-2中描述的部分啟動(dòng)序列事件解釋如下:
preinitialize:在初始化之前觸發(fā),對(duì)于容器來(lái)說(shuō),所有子組件尚未定義。一般來(lái)說(shuō),不會(huì)在該事件觸發(fā)時(shí)配置組件;
initialize:當(dāng)組件或容器完成構(gòu)造,并設(shè)置初始化屬性后觸發(fā)。在這個(gè)階段,對(duì)于容器,其所有的子組件的preinitialize事件已經(jīng)觸發(fā),但是這些子組件還沒(méi)有完成布局;
creationComplete:當(dāng)應(yīng)用或組件(包括所有子組件)完成構(gòu)造、布局和繪制可見(jiàn)時(shí)觸發(fā)。當(dāng)creationComplete事件發(fā)生時(shí),組件已經(jīng)被創(chuàng)建出來(lái),因此開發(fā)者也能夠訪問(wèn)同組件相關(guān)的屬性,比如height、width等屬性。開發(fā)者通常使用這個(gè)事件來(lái)對(duì)應(yīng)用進(jìn)行初始化配置。比如為某些應(yīng)用組件添加偵聽器,調(diào)用Web服務(wù)等;
applicationComplete:所有的組件初始化完成并顯示。
如我們剛才提到的,在事件被觸發(fā)后,F(xiàn)lash Player就會(huì)創(chuàng)建事件對(duì)象,并逐一檢查"事件旅程"上的節(jié)點(diǎn)是否針對(duì)發(fā)生的事件注冊(cè)了偵聽器,為事件對(duì)象賦值,并調(diào)用偵聽器。事件對(duì)象源自flash.events.Event類。事件對(duì)象currentTarget屬性的值會(huì)在事件流中改變,而target屬性則不會(huì)變化。(關(guān)于事件對(duì)象,我們將在6.3節(jié)(見(jiàn)第106頁(yè))深入討論)由此,開發(fā)者能夠通過(guò)
currentTarget屬性獲知事件旅程現(xiàn)在停在了哪個(gè)節(jié)點(diǎn)上。
currentTarget屬性:事件旅程中,currentTarget屬性代表了Flash Player正在檢查的節(jié)點(diǎn)對(duì)象。比如,當(dāng)Flash Player遍歷到ctnButtons對(duì)象,那么event.currentTarget就是ctnButtons對(duì)象。
target屬性:target屬性就是發(fā)生事件的對(duì)象。在信號(hào)燈應(yīng)用中,event.target就是用戶所點(diǎn)擊的按鈕對(duì)象,在事件旅程中,該屬性的值始終不變。信號(hào)燈應(yīng)用中,偵聽器myEventHandler利用event.target來(lái)獲取被點(diǎn)擊按鈕上的標(biāo)簽數(shù)據(jù)。此時(shí)賦給event.currentTarget屬性的則是HBox容器對(duì)象ctnButtons。
2. type屬性(String類型)
當(dāng)用戶進(jìn)行鼠標(biāo)操作時(shí),F(xiàn)lash Player會(huì)自動(dòng)調(diào)度鼠標(biāo)事件MouseEvent。操作可能是鼠標(biāo)點(diǎn)擊、移動(dòng)、滑動(dòng)滾輪等。這些不同的操作都是通過(guò)事件類型來(lái)標(biāo)記的。
type屬性返回的字符串表明事件的類型。代表事件類型的字符串是大小寫敏感的。Flex以常量的形式內(nèi)置了許多事件類型,如Event.unloaded和MouseEvent.CLICK。
3. cancellable屬性(String類型)和preventDefault()方法
默認(rèn)情況下,許多事件都有 Flash Player 執(zhí)行的關(guān)聯(lián)行為。比如,如果用戶在文本字段中鍵入一個(gè)字符,則默認(rèn)行為就是在文本字段中顯示該字符。如果需要取消TextEvent.TEXT_INPUT事件的默認(rèn)行為,你可以使用preventDefault()方法來(lái)阻止顯示所鍵入的字符。
不可取消行為的一個(gè)示例是與Event.REMOVED事件關(guān)聯(lián)的默認(rèn)行為,只要Flash Player從顯示列表中刪除顯示對(duì)象,就會(huì)生成該事件。由于無(wú)法取消默認(rèn)行為(刪除元素),因此preventDefault()方法對(duì)此默認(rèn)行為無(wú)效。
開發(fā)者可以使用Event.cancelable屬性來(lái)檢查是否可以阻止與特定事件關(guān)聯(lián)的默認(rèn)行為。如果屬性Event.cancelable的值為true,則可以使用preventDefault()來(lái)取消默認(rèn)行為,否則,preventDefault()無(wú)效。