The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks
     简单组件一般都是现存 Flex 组件的子类,它们通过设置 skpins 或 styles 属性来修改父组件的外观,或者添加一些新的功能。比如,为 Button 控件增加一个新的事件类型,或者更改
DataGrid 控件缺省的 styles 和 skins。
在高级组件中,通常会执行以下动作: 
1.  更改已有组件的可视化外观或者可视化特性。
2. 创建复合组件,将两个或者多个组件包装在其中。 
3. 通过继承UIComponent 类来创建组件。
    我们通常用继承现存类的方式来创建组件。比如,要创建基于 Button 的控件,我们就创建mx.controls.Button 类的一个子类。要开发自己的组件,则需要创建mx.core.UIComponent 类的子类。
关于重载 UIComponent 类的 protected 方法
    Flex 所有的可视化组件都是UIComponent 类的子类。 因此,可视化组件继承了 UIComponent类所定义的 methods,properties,events,styles 和 effects。
     要创建高级的可视化组件,必须实现一个构造器(constructor)。另外要有选择性地重载下表中 UIComponent 类的一个或者多个 protected 方法: 
    commitProperties()  提交组件所有的属性变化。要么使属性同时更改,要么确保属性按照特定顺序设置。 
    createChildren()       创建组件的子组件。
    比如,ComboBox 控件包含了一个 TextInput 控件和一个 Button 控件作为它的子组件。
    LayoutChrome()   定义 Container 类的子类容器的 border 区域。 
    measure()               设置组件的缺省 size 和缺省的最小 size。 
    updateDisplayList()   根据以前所设置的属性和样式来确定组件的子组件在屏幕上的大小(size)及位置(position) ,并且画出组件所使用的所有皮肤( skins)及图形化元素。组件的父容器负责确定组件本身大小(size)。
 
     组件的使用者不会直接调用所有这些方法。 
关于失效(机制)的方法?
     在组件的生命周期中,应用可能会改变组件的大小和位置,更改组件的属性来控制组件的显示,或者更改组件的样式(styles)和皮肤(skin)属性。比如,可以更改组件中所显示的
文本(Text )的字体(Font)大小。 作为变更字体大小工作的一部分,组件的大小也可能随之发生变化,这就需要 Flex 去更新应用的布局。布局操作需要Flex 调用自定义组件的commitProperties(), measure(), layoutChrome(), 以及 updateDisplayList()方法。
    应用通过程序来更改字体大小的执行速度大大快于 Flex 更新应用的速度。因此,你应该在确定最终要更改的字体之后再更新布局。 另外一个场景就是,当你设置了组件的多个属性后,比如 Button 控件的 label 和 icon 属性,你肯定会想让所有属性被设置后一次性执行 commitProperties(), measure(), 和 updateDisplayList()方法,而不是设置过 label 属性后执行一遍这些方法,然后在设置 icon属性后又执行一次这些方法。
    另外,可能有几个组件同时改变了它们的字体大小。这时应该让 Flex 去协调布局操作,以消除任何冗余过程,而不是在每个组件更新它的字体大小之后都执行一次布局操作。
     Flex 使用一种“失效机制(invalidation mechanism)”来同步组件的更改。Flex 用一系列方法的调用来标记组件的某些东西已经发生变化,并需要 Flex 去调用组件的commitProperties(), measure(), layoutChrome(),或者 updateDisplayList()方法。通过这种办法,Flex 实现了“失效机制” 。 
    下表描述了有关“失效(invalidation)”方法: 
     invalidateProperties()   通知组件,以使下次屏幕更新时,它的commitProperties()方法能被调用。 
     invalidateSize()            通知组件,以使下次屏幕更新时,它的 measure()方法能被调用。 
     invalidateDisplayList()   通知组件,以使下次屏幕更新时它的 layoutChrome()方法和updateDisplayList()方法能被调用。
    当组件调用一个“失效”方法,它就通知 Flex,该组件已经被更新。当多个组件调用失效方法,Flex 会协调这些更新,以使这些更新操作下一次屏幕更新时一起执行。
    通常,组件使用者不必直接调用这些“失效”方法。这些”失效”方法被组件的 setter 方法或者组件的其他方法在需要的时候调用. 
 
关于组件实例化的生命周期 
    组件实例化生命周期描述了用组件类创建组件对象时所发生的一系列步骤.作为生命周期的一部分,Flex 自动调用组件的方法,发出事件,并使组件可见。 
    下面例子用 ActionScript 创建一个 Button 控件,并将其加入到容器之中: 
    //创建一个 Box 容器。 
    var boxContainer:Box = new Box(); 
    //设置 Box 容器 
    … 
    //创建 Button 控件。 
    var b:Button = new Button() 
    //设置 button 控件。 
    b.label = "Submit"; 
    ... 
    // 将 Button 添加到 Box 容器中。 
    boxContainer.addChild(b); 下面的步骤显示了用代码创建一个 Button 控件,并将这个控件添加到 Box 容器中时所发生的一切: 
    1.  调用了组件的构造函数,如下面代码所示: 
    // Create a Button control.  
    var b:Button = new Button() 
    2.  通过设置组件的属性对组件进行了设置,如下面代码所示: 
    // Configure the button control. 
    b.label = "Submit"; 
    组件的 setter 方法将会调用 invalidateProperties(), invalidateSize(), 或者invalidateDisplayList() 方法. 
    3.  调用 addChild()方法将该组件添加到父组件中,如下代码所示: 
    // Add the Button control to the Box container. 
    boxContainer.addChild(b); 
    Flex 执行以下动作: 
    4.   将 component 的 parent 属性设置为对父容器的引用. 
    5.  计算组件的样式(style) 设置.  
    6.  在组件上分发preinitialize 事件.  
    7.  调用组件的createChildren() 方法.  
    8.  调用invalidateProperties(), invalidateSize()和 invalidateDisplayList()方法以触发后续到来的,下一个“渲染事件”(render?event)期间对 commitProperties(), measure(),或 updateDisplayList()方法的调用。 
    这个规则唯一一个例外就是当用户设置组件的 height 和 width 属性时, Flex 不会调用measure() 方法.  
    9.  在组件上分发initialize 事件。此时,组件所有的子组件都被初始化,但是组件没有改更size 和处理布局。可以利用这个事件在组件布局之前执行一些附加的处理。  
    10. 在父容器上分发 childAdd 事件.  
    11. 在父容器上分发initialize 事件.  12. 在下一个“渲染事件”(render?event)中, Flex 执行以下动作:  
    a.  调用组件的 commitProperties()方法.  
    b.  调用组件的 measure()方法.  
    c.  调用组件的 layoutChrome()方法.  
    d.  调用组件的 updateDisplayList()方法.  
    e.  在组件上分发 updateComplete 事件.  
    13. 如果commitProperties(), measure()或者 updateDisplayList()方法调用了 invalidateProperties(), invalidateSize(),或 invalidateDisplayList()方法,则 Flexh 会分发另外一个 render 事件. 
    14. 在最后的render 事件发生后, Flex 执行以下动作:  
    a.  通过设置组件的 visible 属性使组件变为可视. 
    b.  在组件上分发 creationComplete 事件.组件的大小(size)和布局被确定.这个事件只在组件创建时分发一次.  
    c.  在组件上分发 updateComplete 事件.无论什么时候,只要组件的布局(layout),位置,大小或其它可视的属性发生变化就会分发这事件,然后组件被更新,以使组件能够被正确地显示. 
    当使用 addChild()方法将组件添加到容器中时,大部分工作都是为了设置这个组件.这是因为直到把组件添加到容器中时,Flex 才能确定它的大小(size),设置它所继承样式(style)属性,或者在屏幕上画出它. 也可以用 MXML,在应用中完成上面的组件添加动作,如下面的例子所示:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Box>
        <mx:Button label="Submit"/>
    </mx:Box>
</mx:Application> 
    在 MXML 中创建组件时,Flex 执行的步骤顺序同用 ActionScript 的步骤顺序相同. 使用 removeChild() 方法可将组件从容器中移出, 如果对这个组件再没有其他的引用,那就相当于使用 Adobe Flash  Player 或 Adobe AIR 的垃圾回收机制将组件从内存中删除. 关于创建组件的步骤 
    为了实现一个组件,就要重载组件的方法,定义新的属性,分发新的事件,或者执行其他任何应用所需的自定义的逻辑.要想实现自己的组件, 请遵循以下这些常规步骤: 
    1.  如果有必要,为组件创建所有的皮肤(skins) . 
    2.  创建 ActionScript 类文件. 
    a.  从一个基类扩展,比如 UIComponent 或者其他的组件类. 
    b.  指定使用者能够通过 MXML 标记进行设置的属性. 
    c.  嵌入(Embed)所有的图片和皮肤文件. 
    d.  实现构造器. 
    e.  实现 UIComponent.createChildren()方法.  
    f.  实现 UIComponent.commitProperties() 方法.  
    g.  实现 UIComponent.measure() 方法.  
    h.  实现 UIComponent.layoutChrome() 方法.  
    i.   实现 UIComponent.updateDisplayList() 方法.  
    j.  增加属性(properties),方法(methods),样式(styles),事件 (events)以及元数据. 
    3.  以 ActionScript 文件或者 SWC 文件的形式部署组件. 
     定义新组件时不一定要重载所有的方法.只需要重载实现组件功能所需的方法.如果创建现存组件的子类,比如 Button 控件或者 VBox 容器,那么必须实现组件中所添加的新功能所需
的方法. 
    例如:实现一个自定义的 Button 控件,该控件使用新的机制来定义缺省大小(size) .在这种情况下,只需要重载 measure()方法.对于这个例子,参见实现 easure() 方法.
或者,要实现 VBox 容器的一个新子类.新子类利用 VBox 类已有的所有有关设定大小(sizing)的逻辑,但是变更了 VBox 类的布局逻辑以实现从底部到顶部的方式来布局容器中的
子控件,而不是自顶向下的布局.在这种情况下,只需要重载updateDisplayList()方法.关于这个例子,见实现 updateDisplayList()方法.
 
关于接口 

    Flex 用接口将组件的基本功能分为离散的单元, 这使得它们可以被 “一块一块” 地实现. 例如,使组件可聚焦(有输入焦点) ,它必须实现 IFocusable 接口;要使它能够参与布局过程,它必须实现 ILayoutClient 接口. 为了简化接口的使用, UIComponent 类实现了下表中定义的所有接口,但是不包括IFocusManagerComponent 接口和 IToolTipManagerClient 接口.但 UIComponent 很多子类实现了 IFocusManagerComponent 和 IToolTipManagerClient 接口. 
    因此,创建 UIComponent 或其子类的子类,就不必实现这些接口.但是,如果要创建的组件不是 UIComponent 的子类,并且还想在 Flex 中使用这个组件,那么就必须实现一个或者多个接口。 
    注意:对于 Flex, Adobe 建议所有的组件都应从 UIComponent 及其子类继承. 
    下表列出了 Flex components 所实现的主要接口:  
    接口                                                           用途 
    IChildList                                                    表明容器中子控件的数量. 
    IDeferredInstantiationUIComponent              表明组件或组件能实施延迟实例化. 
    IFlexDisplayObject                                       指定皮肤元素的接口. 
    IFocusManagerComponent                           表明组件或者对象是可聚焦的,这意味着组件可以从 FocusManager 获取焦点. 
    UIComponent                                             组件没有实现 Ifocusable 接口,因为有些组件不打算接受焦点. 
    IInvalidating                                               表明组件或者对象能够使用”失效机制”去执行延迟的,而不是立即的属性提交( commitment), 度量(measurement), 以及画出(drawing) 或布局( layout). 
    ILayoutManagerClient                                  表明组件或者对象能够参与 LayoutManager 的提交(commit) ,度量(measure)和更新次序(update sequence)  
    IPropertyChangeNotifier                               表明组件支持特定形式的事件传播. 
    IRepeaterClient                                           表明组件或者对象能够被用于 Repeater 类. 
    IStyleClient                                                 表明组件能够从其他的对象继承样式,并且支持setStyle() 和 getStyle() 方法. 
    IToolTipManagerClient                                  表明组件有一个 toolTip 属性,并且因此可以被ToolTipManager 所监控. 
    IUIComponent                                            定义组件能够成为布局管理器或列表的子组件所必须实现的基本 APIs.
    IValidatorListener                                       表明组件能够监听校验(validation)事件,并且因此能够显示校验状态,比如一个红色边框和显示
校验错误的提示信息(tooltips)
posted on 2011-07-09 17:37 Eric_jiang 阅读(428) 评论(0)  编辑  收藏 所属分类: Flex

只有注册用户登录后才能发表评论。


网站导航: