Flex 3入門教程: 在ActionScript 中構建自定義組件

可以使用ActionScript創建可重用的組件,並且在你的Flex程序中可以作爲標籤引用這個組件。在ActionScript中創建的組件能夠包含圖像元素,自定義業務邏輯,或者擴展已經存在的Flex組件。

在ActionScript中,Flex組件實現了類層次結構。每一個組件,都是Action類的實例。下圖展示了這種層次結構的一部分。

所有Flex可視組件都是源自於UIComponent類。要創建自己的組件,你可以創建一個繼承UIComponent的類,或者繼承UIComponent子類的類。

使用類作爲自定義組件的超類,取決於你要實現的功能。例如,你或許需要一個自定義的按鈕控件。你可以創建一個UIComponent類的子類,然後重寫Flex Button 類的所有功能。更好更快創建自定義按鈕組建的方法是創建一個Flex Button組件的子類,然後在自定義類中進行修改。


創建一個簡單的ActionScript組件

引用自定義組件的屬性和方法

爲自定義組件應用樣式

創建一個高級的ActionScript組件

創建一個複合ActionScript組件


鏈接:你可以在MXML中創建自定義組件。更多的信息,參看Building components in MXML Quick Start.


創建一個簡單的ActionScript組件


當你要在ActionScript 中定義一個組件時,不要創建一個組件,而是修改一個已經存在的組件的行爲。在下邊的例子中,創建一個ComboBox類的子類,來創建一個自定義的ComboBox,命名爲CountryComboBox——重新組裝的國家列表。


注意:在MXML中實例化你的組件,要使用類名作爲標籤名。


你可以放置自定義組件在項目的根目錄或者子目錄中。Adobe推薦後者。在這個例子中,自定義被放置在叫做components的子文件夾中,在ActionScript相當於components包。在主應用程序的MXML文件中,映射這個文件夾的命名空間爲custom,並且使用完全合格的標籤名<custom:CountryComboBox>來引用這個組件。


注意:在真實世界的應用程序中,你可能會看到自定義組件被放置在倒置的域名結構的包結構中(例如:xmlns:custom=”com.adobe.quickstarts.customcomponents.*”)。這種習慣可以避免命名空間衝突,當不同的製造商,使用相同的名字。例如,在你的應用程序中,2個組件庫也許都含有Map組件,如果一個在com.vendorA包中另一個在com.vendorB包中,那麼他們就不會起衝突


例子

components/CountryComboBox.as

 

  1. package components
  2. {
  3.     import mx.controls.ComboBox;
  4.     public class CountryComboBox extends ComboBox
  5.     {
  6.         public function CountryComboBox()
  7.         {
  8.             dataProvider = [ "United States""United Kingdom" ];
  9.         }
  10.     }
  11. }

應用程序MXML文件


 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application
  3.     xmlns:mx="http://www.adobe.com/2006/mxml"
  4.     xmlns:custom="components.*"
  5.     width="220" height="115">
  6.     <custom:CountryComboBox />
  7. </mx:Application>

引用自定義組件的屬性和方法


CountryComboBox類繼承了ComboBox類,所以能夠在初始化自定義組件的MXML標籤中或者在<mx:Script>標籤中的ActionScript中,引用所有屬性和方法。下邊的例子指定了rowCount屬性,並且爲自定義組件的close事件指定了監聽器。


例子

components/CountryComboBox.as

 


 

  1. package components
  2. {
  3.     import mx.controls.ComboBox;
  4.     public class CountryComboBox extends ComboBox
  5.     {
  6.         public function CountryComboBox ()
  7.         {
  8.             dataProvider = [ "United States""United Kingdom" ];
  9.         }
  10.     }
  11. }

應用程序MXML文件

 


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application
  3.     xmlns:mx="http://www.adobe.com/2006/mxml"
  4.     xmlns:custom="components.*"
  5.     width="270" height="170">
  6.     <mx:Script>
  7.         <![CDATA[
  8.             import Flash.events.Event;
  9.             private function handleCloseEvent(eventObj:Event):void
  10.             {
  11.                 status.text = "You selected: /r" + countries.selectedItem as String;
  12.             }  
  13.         ]]>
  14.     </mx:Script>
  15.     <mx:Panel
  16.         title="Custom component inheritance"
  17.         paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
  18.         <custom:CountryComboBox
  19.             id="countries" rowCount="5"
  20.             close="handleCloseEvent(event);"
  21.         />
  22.         <mx:Text id="status" text="Please select a country from the list above." width="136"/>      
  23.     </mx:Panel>
  24. </mx:Application>

爲自定義組件應用樣式


Style 屬性定義了一個組件的感觀,從字體大小到背景顏色。自定義的ActionScript組件繼承了超類的所有樣式,所以你也可以使用同樣的方式來設置樣式。


要在自定義組件中改變樣式屬性,可以在組件構造器中使用setStyle()方法。這樣會應用相同的樣式到所有的組件的實例中,但是組件的用戶可以在MXML標記中覆蓋setStyle()方法設置的樣式。所有在組件類文件中爲設置的樣式均從超類繼承。


在下邊的例子中,創建了一個PaddedPanel自定義組件,它擴展了Panel組件,並且在組件四周一律使用10像素的邊白。使用這個自定義組件,比每次使用Panel組件都要設置4個樣式屬性(paddingLeft, paddingRight, paddingTop, and paddingBottom)更簡單,也就是說,結果是更少的編碼,沒有重複勞動。

例子

components/PaddedPanel.as


  1. package components
  2. {
  3.     import mx.containers.Panel;
  4.     public class PaddedPanel extends Panel
  5.     {
  6.         public function PaddedPanel()
  7.         {
  8.             // Call the constructor of the superclass.
  9.             super();
  10.             // Give the panel a uniform 10-pixel
  11.             // padding on all four sides.
  12.             setStyle("paddingLeft"10);
  13.             setStyle("paddingRight"10);
  14.             setStyle("paddingTop"10);
  15.             setStyle("paddingBottom"10);
  16.         }
  17.     }
  18. }

應用程序MXML文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application
  3.     xmlns:mx="http://www.adobe.com/2006/mxml"
  4.     xmlns:custom="components.*"
  5.     width="300" height="130">
  6.     <custom:PaddedPanel title="Custom component styles">
  7.         <mx:Text text="This is a padded panel component."/>
  8.     </custom:PaddedPanel>  
  9. </mx:Application>

 創建一個高級的ActionScript組件


當使用ActionScript組件的普遍目的是創建可配置和可重用的組件。例如,創建一個ActionScript組件,它帶有屬性,分發時間,定義了新的樣式,具有自定義的皮膚,或其他的個性化的設置。


當創建一個自定的ActionScript組件時,一個設計上要考慮的事情是可重用性。也就是說,你希望創建一個緊緊的綁定帶你的應用程序的組件,還是能夠在多個應用中可重用的組件?


編寫與特定應用程序緊耦合的組件,經常是組件依賴於應用程序的結構,變量名或其他細節。如果你改變了應用程序,你可能需要修改緊耦合的組件來反映這種變化。一個緊耦合的組件,在沒有重寫的情況下很難應用到其他應用程序中。


設計一個鬆耦合的組件用於重用。鬆耦合的組件需要有清晰可辨的接口來指定如何向組件傳遞信息,如何將將結果傳回應用程序。


典型的鬆耦合組件是使用屬性來向組件傳遞信息。這些屬性通過默認存取器(setter和getter方法)來定義,指定參數的類型。在下邊的例子中,CountryComboBox自定義組件定義了公共的userShortNames屬性,此屬性通過使用get userShortNames()和set useShortNames()存取器方法暴露_ userShortNames私有屬性。


私有屬性_userShortNames的Inspectable 元數據標籤定義了一個特性,這個特性出現在Adobe? Flex? Builder?中的屬性提示和標籤內省器中。也可以使用這個元數據標籤限制允許的屬性值。


注意:所有公共屬性出現在MXML的代碼提示和屬性檢查器中。如果你有關於屬性的額外的信息,這些信息能夠幫助代碼提示或屬性檢查器(像枚舉型的值,或這個字符串實際是文件路徑),那麼也把額外的信息添加到[Inspectable]元數據中。


MXML代碼提示和屬性檢查器來於相同的數據,所以,如果在一箇中顯示出來那麼在另一箇中也應該一直顯示出來。


在另一方面,ActionScript代碼提示,不需要元數據也可以正常工作,所以你在ActionScript中依據所在的上下文一直都可以看待適當的代碼提示。Flex Builder使用public/protected/private/static等等修飾符加當前所在範圍計算出ActionScript代碼提示。


定義組件向主應用程序返回信息的最佳實踐是設計組件分發事件,事件中包含要返回的數據。那樣,主函數能夠定義時間監聽器來處理時間,並且採取適當的行動。也可以使用數據綁定在事件中。在下邊的例子中,使用Bindable元數據標籤是userShortName編程一個被綁定的屬性。隱含的userShortName屬性的setter發送改變事件,這個過程使用了的Flex 框架的內部的機制,來使數據綁定正常工作。


連接:有些文章比這個引導性的快速指南更多的描述關於在ActionScript中創建高級組件的應用。全面描述這一主題,可以查看” Creating Advanced Visual Components in ActionScript”在Creating and Extending Adobe Flex 3 Components.


例子

components/CountryComboBox.as



 

  1. package components
  2. {
  3.     import mx.controls.ComboBox;
  4.     import Flash.events.Event;
  5.     public class CountryComboBox extends ComboBox
  6.     {
  7.         private var countryArrayShort:Array = ["US""UK"];
  8.         private var countryArrayLong:Array = ["United States""United Kingdom"];
  9.         // Determines display state. The inspectable metadata tag
  10.         // is used by Flex Builder 3.
  11.         [Inspectable(defaultValue=true)]
  12.         private var _useShortNames:Boolean = true;
  13.         // Implicit setter
  14.         public function set useShortNames(state:Boolean):void
  15.         {
  16.             // Call method to set the dataProvider based on the name length.
  17.             _useShortNames = state;
  18.             if (state)
  19.             {
  20.                 this.dataProvider = countryArrayShort;
  21.             }
  22.             else
  23.             {
  24.                 this.dataProvider = countryArrayLong;
  25.             }
  26.             // Dispatch an event when the value changes
  27.             // (used in data binding).
  28.           dispatchEvent(new Event("changeUseShortNames"));
  29.         }
  30.         // Allow other components to bind to this property
  31.         [Bindable(event="changeUseShortNames")]
  32.         public function get useShortNames():Boolean
  33.         {
  34.             return _useShortNames;
  35.         }               
  36.     }
  37. }

應用程序 MXML文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application
  3.     xmlns:mx="http://www.adobe.com/2006/mxml"
  4.     xmlns:custom="components.*"
  5.     viewSourceURL="src/MxmlComponentAdvanced/index.html"
  6.     width="260" height="200">
  7.     <mx:Panel
  8.         title="Advanced custom components"
  9.         paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
  10.         <!-- Set a custom property on a custom component -->
  11.         <custom:CountryComboBox
  12.             id="countries"
  13.             useShortNames="false"/>
  14.         <!--
  15.             Use data binding to display the latest state
  16.             of the property.
  17.         -->
  18.         <mx:Label text="useShortNames = {countries.useShortNames}"/>   
  19.         <mx:ControlBar horizontalAlign="right">
  20.             <mx:Button
  21.                 label="Toggle Display"
  22.                 click="countries.useShortNames = !countries.useShortNames;"/>
  23.         </mx:ControlBar>
  24.     </mx:Panel>
  25. </mx:Application>

 

創建複合 ActionScript 組件

 

例子
components/NumericDisplay.as

  1. package components
  2. {
  3.     import mx.containers.VBox;
  4.     import mx.containers.Tile;
  5.     import mx.controls.TextInput;
  6.     import mx.controls.Button;
  7.     import mx.events.FlexEvent;
  8.     import Flash.events.Event;
  9.     import Flash.events.MouseEvent;
  10.     public class NumericDisplay extends VBox
  11.     {
  12.         private var display:TextInput;
  13.         private var buttonsTile:Tile;
  14.         // Expose the _numButtons property to the
  15.         // visual design view in Flex Builder 3.
  16.         [Inspectable(defaultValue=10)]
  17.         private var _numButtons:uint = 10;
  18.         public function NumericDisplay()
  19.         {
  20.             addEventListener(FlexEvent.INITIALIZE, initializeHandler);
  21.         }
  22.         
  23.         // numButtons is a public property that determines the
  24.         // number of buttons that is displayed
  25.         [Bindable(event="numButtonsChange")]
  26.         public function get numButtons():uint
  27.         {
  28.             return _numButtons;
  29.         }
  30.         public function set numButtons(value:uint):void
  31.         {
  32.             _numButtons = value;
  33.             dispatchEvent(new Event("numButtonsChange"));
  34.         }
  35.         
  36.         // Gets called when the component has been initialized
  37.         private function initializeHandler(event:FlexEvent):void
  38.         {
  39.             // Display the component
  40.             paint();
  41.         }
  42.         // Add the label of the clicked button to the display
  43.         private function buttonClickHandler(event:MouseEvent):void
  44.         {
  45.             display.text += (event.target as Button).label;
  46.         }
  47.         
  48.         // Display the component
  49.         private function paint():void
  50.         {
  51.             // Create the number display
  52.             display = new TextInput();
  53.             display.width=185;
  54.             addChild(display);
  55.             // Create a Tile container to
  56.             // hold the buttons.
  57.             buttonsTile = new Tile();
  58.             addChild (buttonsTile);
  59.             
  60.             // Create the buttons and add them to
  61.             // the Tile container.
  62.             for (var i:uint = 0; i < _numButtons; i++)
  63.             {
  64.                 var currentButton:Button = new Button();
  65.                 currentButton.label = i.toString();
  66.                 currentButton.addEventListener(MouseEvent.CLICK, buttonClickHandler);
  67.                 buttonsTile.addChild (currentButton);
  68.             }
  69.         }
  70.     }
  71. }

 

components/PaddedPanel.as

 

  1. package components
  2. {
  3.     import mx.containers.Panel;
  4.     public class PaddedPanel extends Panel
  5.     {
  6.         public function PaddedPanel()
  7.         {
  8.             // Call the constructor of the superclass.
  9.             super();
  10.             
  11.             // Give the panel a uniform 10-pixel 
  12.             // padding on all four sides.
  13.             setStyle ("paddingLeft"10);
  14.             setStyle ("paddingRight"10);
  15.             setStyle ("paddingTop"10);
  16.             setStyle ("paddingBottom"10);
  17.         }
  18.     }
  19. }

應用程序 MXML 文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application 
  3.     xmlns:mx="http://www.adobe.com/2006/mxml" 
  4.     xmlns:custom="components.*"
  5.     viewSourceURL="src/ASComponentComposite/index.html"
  6.     width="300" height="225">
  7.     <custom:PaddedPanel 
  8.         title="Composite component">
  9.         <custom:NumericDisplay numButtons="10"/>        
  10.     </custom:PaddedPanel>
  11. </mx:Application>

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章