實現一個自定義組件

如果要創建一個自定義組件,你需要重寫UIComponent類的某些方法,最少需要重寫如下方法:構造函數, createChildren(), commitProperties(), measure(), layoutChrome(), updateDisplayList() 。
基礎語句結構如下:

  1. package myComponents 
  2. public class MyComponent extends UIComponent 
  3. {    .... } 


注意包名與你的磁盤目錄結構一致。接下來一一講解每個方法的重寫。
構造函數
示例如下:
public function 類名() {
super();
}
注意,AS3中構造函數不支持重載。
createChildren()
此方法的作用是在此自定義組件中創建子組件。
此方法不用你去調用,Flex在你將此自定義組件使用addChild方法加入到父組件時自動調用。示例如下:

  1. // Declare two variables for the component children. 
  2. private var text_mc:TextArea; 
  3. private var mode_mc:Button; 
  4. override protected function createChildren():void { 
  5.     // Call the createChildren() method of the superclass. 
  6.     super.createChildren(); 
  7.     // Test for the existence of the children before creating them. 
  8.     // This is optional, but do this so a subclass can create a different 
  9.     // child. 
  10.     if (!text_mc)     { 
  11.         text_mc = new TextArea(); 
  12.         text_mc.explicitWidth = 80
  13.         text_mc.editable = false
  14.         text_mc.addEventListener("change", handleChangeEvent); 
  15.         // Add the child component to the custom component. 
  16.         addChild(text_mc); 
  17.     } 
  18.     // Test for the existence of the children before creating them. 
  19.     if (!mode_mc)     {    
  20.         mode_mc = new Button(); 
  21.         mode_mc.label = "Toggle Editing"
  22.         mode_mc.addEventListener("click", handleClickEvent); 
  23.         // Add the child component to the custom component. 
  24.         addChild(mode_mc); 
  25.     } 


上例使用createChildren()在此自定義組件中加入了一個Label和一個Button。
commitProperties()
此方法是在修改組件屬性時使用。
此方法不用你去調用。當你調用invalidateProperties()(刷新屬性)、addChild()(增加子組件)方法時,Flex會自動調用此方法。這樣組件在下次顯示時,就能以新的屬性來顯示。
此方法還有一個作用是爲measure()方法提供最新的屬性信息。
measure()
此方法的作用是設置組件的默認尺寸。
此方法不用你去調用。當你調用invalidateSize ()(刷新尺寸)、addChild()(增加子組件)方法時,Flex會自動調用此方法。這樣組件在下次顯示時,就能以默認尺寸來顯示。
如果你顯式的設置了組件的尺寸,如<mx:Button height="10" width="10"/>,Flex就不用調用此方法了。要注意,measure()方法只是設置組件的默認尺寸,在 updateDisplayList()方法中,組件具備的實際尺寸(actual size)與默認尺寸可能不同。
Flex中的每個組件都是有默認尺寸的。如這樣寫:<mx:Button />,Flex就會自動給一個尺寸。如果你想重寫默認尺寸,可以重新設置measuredHeight 、measuredWidth、measuredMinHeight、measuredMinWidth。如下例:

  1. package myComponents 
  2.     // asAdvanced/myComponents/DeleteTextArea.as 
  3.     import mx.controls.Button; 
  4.     public class BlueButton extends Button { 
  5.         public function BlueButton() { 
  6.             super(); 
  7.         } 
  8.        override protected function measure():void { 
  9.             super.measure(); 
  10.             measuredWidth=100
  11.             measuredMinWidth=50
  12.             measuredHeight=50
  13.             measuredMinHeight=25
  14.         } 
  15.     } 


然後在MXML中使用:

  1. <?xml version="1.0"?> 
  2. <!-- asAdvanced/ASAdvancedMainBlueButton.mxml --> 
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
  4.     xmlns:MyComp="myComponents.*" > 
  5.     <mx:VBox> 
  6.         <MyComp:BlueButton/> 
  7.         <mx:Button/> 
  8.     </mx:VBox> 
  9. </mx:Application> 


此中的BlueButton就會以默認值100寬,50高來顯示。
layoutChrome()
一些容器類(Container)或其子類採用此方法設置組件的border Area(邊框區域)。
此方法不用你去調用。當你調用invalidateDisplayList ()(刷新顯示)方法時,Flex會自動調用此方法。這樣組件在下次顯示時,就能以新的邊框來顯示。
典型的用法是你可以重寫RectangularBorder類。
一個將組件的邊框區域(border Area)和內容區域(content area)分開處理的原因是當Container.autoLayout=false時。
總括的來講,layoutChrome()是用來處理邊框區域的刷新顯示,而updateDisplayList()用來處理內容區域的刷新顯示。
updateDisplayList()
此方法不用你去調用。當你調用invalidateDisplayList ()(刷新顯示)、addChild()(增加子組件)方法時,Flex會自動調用此方法。這樣組件在下次顯示時,就能以新的樣子來顯示。其實類似VC++中的PAINT消息處理。
此方法的主要作用爲:
A.更改組件的尺寸和位置。要改變尺寸,在此方法中使用setActualSize()方法,而不是使用width和height屬性來完成。要改變位置,在此方法中使用move()方法,而不是使用x和y屬性來完成。
B.繪製可視元素,如皮膚、樣式、邊框。你可以使用Flash Drawing API來完成。
函數的原型爲:
protected function updateDisplayList(unscaledWidth:Number,
    unscaledHeight:Number):void
兩個參數分別爲此自定義組件的寬度和高度。當然如果設置父容器設置scaleY=2,你設置unscaledHeight=100,那麼最終呈現的是200高度的組件。
第一個功能示例:

  1. package myComponents 
  2.     // asAdvanced/myComponents/BottomUpVBox.as 
  3.     import mx.containers.VBox; 
  4.     import mx.core.EdgeMetrics; 
  5.     import mx.core.UIComponent; 
  6.     public class BottomUpVBox extends VBox 
  7.     { 
  8.         public function BottomUpVBox() { 
  9.             super(); 
  10.         } 
  11.         override protected function updateDisplayList(unscaledWidth:Number, 
  12.             unscaledHeight:Number):void { 
  13.             super.updateDisplayList(unscaledWidth, unscaledHeight); 
  14.             // Get information about the container border area. 
  15.             // The usable area of the container for its children is the 
  16.             // container size, minus any border areas. 
  17.             var vm:EdgeMetrics = viewMetricsAndPadding
  18.             // Get the setting for the vertical gap between children. 
  19.             var gap:Number = getStyle("verticalGap"); 
  20.             // Determine the y coordinate of the bottom of the usable area 
  21.             // of the VBox. 
  22.             var yOfComp:Number = unscaledHeight-vm.bottom; 
  23.             // Temp variable for a container child. 
  24.             var obj:UIComponent; 
  25.             for (var i:int = 0; i < numChildren; i++) 
  26.             { 
  27.                 // Get the first container child. 
  28.                 obj = UIComponent(getChildAt(i)); 
  29.                 // Determine the y coordinate of the child. 
  30.                yOfCompyOfComp = yOfComp - obj.height; 
  31.                 // Set the x and y coordinate of the child. 
  32.                 // Note that you do not change the x coordinate. 
  33.                 obj.move(obj.x, yOfComp); 
  34.                 // Save the y coordinate of the child, 
  35.                 // plus the vertical gap between children. 
  36.                 // This is used to calculate the coordinate 
  37.                 // of the next child. 
  38.                 yOfCompyOfComp = yOfComp - gap; 
  39.             } 
  40.          } 
  41.     } 


第二個功能示例:

  1. override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { 
  2.     super.updateDisplayList(unscaledWidth, unscaledHeight); 
  3.     // Draw a simple border around the child components. 
  4.     graphics.lineStyle(1, 0x000000, 1.0); 
  5.     graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);            

 

出自:http://www.ebibi.com/i/experience/2011/0307/3512.html

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