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. packagecomponents
  2. {
  3. importmx.controls.ComboBox;
  4. publicclassCountryComboBoxextendsComboBox
  5. {
  6. publicfunctionCountryComboBox()
  7. {
  8. dataProvider=["UnitedStates","UnitedKingdom"];
  9. }
  10. }
  11. }

应用程序MXML文件


  1. <?xmlversion="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. packagecomponents
  2. {
  3. importmx.controls.ComboBox;
  4. publicclassCountryComboBoxextendsComboBox
  5. {
  6. publicfunctionCountryComboBox()
  7. {
  8. dataProvider=["UnitedStates","UnitedKingdom"];
  9. }
  10. }
  11. }

应用程序MXML文件


  1. <?xmlversion="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. importFlash.events.Event;
  9. privatefunctionhandleCloseEvent(eventObj:Event):void
  10. {
  11. status.text="Youselected:/r"+countries.selectedItemasString;
  12. }
  13. ]]>
  14. </mx:Script>
  15. <mx:Panel
  16. title="Customcomponentinheritance"
  17. paddingTop="10"paddingBottom="10"paddingLeft="10"paddingRight="10">
  18. <custom:CountryComboBox
  19. id="countries"rowCount="5"
  20. close="handleCloseEvent(event);"
  21. />
  22. <mx:Textid="status"text="Pleaseselectacountryfromthelistabove."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. packagecomponents
  2. {
  3. importmx.containers.Panel;
  4. publicclassPaddedPanelextendsPanel
  5. {
  6. publicfunctionPaddedPanel()
  7. {
  8. //Calltheconstructorofthesuperclass.
  9. super();
  10. //Givethepanelauniform10-pixel
  11. //paddingonallfoursides.
  12. setStyle("paddingLeft",10);
  13. setStyle("paddingRight",10);
  14. setStyle("paddingTop",10);
  15. setStyle("paddingBottom",10);
  16. }
  17. }
  18. }

应用程序MXML文件

  1. <?xmlversion="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:PaddedPaneltitle="Customcomponentstyles">
  7. <mx:Texttext="Thisisapaddedpanelcomponent."/>
  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. packagecomponents
  2. {
  3. importmx.controls.ComboBox;
  4. importFlash.events.Event;
  5. publicclassCountryComboBoxextendsComboBox
  6. {
  7. privatevarcountryArrayShort:Array=["US","UK"];
  8. privatevarcountryArrayLong:Array=["UnitedStates","UnitedKingdom"];
  9. //Determinesdisplaystate.Theinspectablemetadatatag
  10. //isusedbyFlexBuilder3.
  11. [Inspectable(defaultValue=true)]
  12. privatevar_useShortNames:Boolean=true;
  13. //Implicitsetter
  14. publicfunctionsetuseShortNames(state:Boolean):void
  15. {
  16. //CallmethodtosetthedataProviderbasedonthenamelength.
  17. _useShortNames=state;
  18. if(state)
  19. {
  20. this.dataProvider=countryArrayShort;
  21. }
  22. else
  23. {
  24. this.dataProvider=countryArrayLong;
  25. }
  26. //Dispatchaneventwhenthevaluechanges
  27. //(usedindatabinding).
  28. dispatchEvent(newEvent("changeUseShortNames"));
  29. }
  30. //Allowothercomponentstobindtothisproperty
  31. [Bindable(event="changeUseShortNames")]
  32. publicfunctiongetuseShortNames():Boolean
  33. {
  34. return_useShortNames;
  35. }
  36. }
  37. }

应用程序MXML文件

  1. <?xmlversion="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="Advancedcustomcomponents"
  9. paddingTop="10"paddingBottom="10"paddingLeft="10"paddingRight="10">
  10. <!--Setacustompropertyonacustomcomponent-->
  11. <custom:CountryComboBox
  12. id="countries"
  13. useShortNames="false"/>
  14. <!--
  15. Usedatabindingtodisplaythelateststate
  16. oftheproperty.
  17. -->
  18. <mx:Labeltext="useShortNames={countries.useShortNames}"/>
  19. <mx:ControlBarhorizontalAlign="right">
  20. <mx:Button
  21. label="ToggleDisplay"
  22. click="countries.useShortNames=!countries.useShortNames;"/>
  23. </mx:ControlBar>
  24. </mx:Panel>
  25. </mx:Application>

创建复合 ActionScript 组件

例子
components/NumericDisplay.as

  1. packagecomponents
  2. {
  3. importmx.containers.VBox;
  4. importmx.containers.Tile;
  5. importmx.controls.TextInput;
  6. importmx.controls.Button;
  7. importmx.events.FlexEvent;
  8. importFlash.events.Event;
  9. importFlash.events.MouseEvent;
  10. publicclassNumericDisplayextendsVBox
  11. {
  12. privatevardisplay:TextInput;
  13. privatevarbuttonsTile:Tile;
  14. //Exposethe_numButtonspropertytothe
  15. //visualdesignviewinFlexBuilder3.
  16. [Inspectable(defaultValue=10)]
  17. privatevar_numButtons:uint=10;
  18. publicfunctionNumericDisplay()
  19. {
  20. addEventListener(FlexEvent.INITIALIZE,initializeHandler);
  21. }
  22. //numButtonsisapublicpropertythatdeterminesthe
  23. //numberofbuttonsthatisdisplayed
  24. [Bindable(event="numButtonsChange")]
  25. publicfunctiongetnumButtons():uint
  26. {
  27. return_numButtons;
  28. }
  29. publicfunctionsetnumButtons(value:uint):void
  30. {
  31. _numButtons=value;
  32. dispatchEvent(newEvent("numButtonsChange"));
  33. }
  34. //Getscalledwhenthecomponenthasbeeninitialized
  35. privatefunctioninitializeHandler(event:FlexEvent):void
  36. {
  37. //Displaythecomponent
  38. paint();
  39. }
  40. //Addthelabeloftheclickedbuttontothedisplay
  41. privatefunctionbuttonClickHandler(event:MouseEvent):void
  42. {
  43. display.text+=(event.targetasButton).label;
  44. }
  45. //Displaythecomponent
  46. privatefunctionpaint():void
  47. {
  48. //Createthenumberdisplay
  49. display=newTextInput();
  50. display.width=185;
  51. addChild(display);
  52. //CreateaTilecontainerto
  53. //holdthebuttons.
  54. buttonsTile=newTile();
  55. addChild(buttonsTile);
  56. //Createthebuttonsandaddthemto
  57. //theTilecontainer.
  58. for(vari:uint=0;i<_numButtons;i++)
  59. {
  60. varcurrentButton:Button=newButton();
  61. currentButton.label=i.toString();
  62. currentButton.addEventListener(MouseEvent.CLICK,buttonClickHandler);
  63. buttonsTile.addChild(currentButton);
  64. }
  65. }
  66. }
  67. }

components/PaddedPanel.as

  1. packagecomponents
  2. {
  3. importmx.containers.Panel;
  4. publicclassPaddedPanelextendsPanel
  5. {
  6. publicfunctionPaddedPanel()
  7. {
  8. //Calltheconstructorofthesuperclass.
  9. super();
  10. //Givethepanelauniform10-pixel
  11. //paddingonallfoursides.
  12. setStyle("paddingLeft",10);
  13. setStyle("paddingRight",10);
  14. setStyle("paddingTop",10);
  15. setStyle("paddingBottom",10);
  16. }
  17. }
  18. }

应用程序MXML 文件

  1. <?xmlversion="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="Compositecomponent">
  9. <custom:NumericDisplaynumButtons="10"/>
  10. </custom:PaddedPanel>
  11. </mx:Application>

你可能感兴趣的:(actionscript)