Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3334395
  • 博文数量: 530
  • 博客积分: 13360
  • 博客等级: 上将
  • 技术积分: 5473
  • 用 户 组: 普通用户
  • 注册时间: 2006-07-13 13:32
文章分类

全部博文(530)

文章存档

2017年(1)

2015年(2)

2013年(24)

2012年(20)

2011年(97)

2010年(240)

2009年(117)

2008年(12)

2007年(8)

2006年(9)

分类: 系统运维

2011-09-17 11:45:55

1.概述
      本文介绍了Gumbo的皮肤框架原理。不象MX的skinning仅是一个简单的图形操作,Gumbo的skin是一个综合的、可以包含多个元素(比如图形元素,文本、图片、转换等),主要亮点如下:
      . 所有可视特征,包括layou都可以在skin中控制。
      . 所有的skin保持简单、一致,Button的皮肤与List Item的皮肤可以是一样的
      . 通过skin parts可以进行皮肤的组合
      . 通过配置文件描述可以容易创建和控制

2.使用场景
最常用场景:
      有一个控件,比如Button,不通过任何ActionScript代码,只用创建一个新的ButtonSkin ,因为skin 文件是MXML,设计人员很容易进行设计皮肤。

其它场景:
      开发人员创建一个自定义组件,但可以自定义皮肤。通过继承SkinnableComponent即可。
      设计人员通过修改CSS就可以改变应用程序的皮肤。

3.详细描述
      每个组件包含四个概念:model, skin, controller和view-specific logic(可视化描述逻辑)。

      model 包含组件的属性和业务逻辑。比如Range model的属性有:minimumValue, maximumValue, stepSize等。方法有:画线。model 不能包含任何可视化或行为信息。

      skin 定义了组件的可视化元素。

      controller 是skin和model的接口。它具有几个关键功能:
      . 定义组件行为,比如:Button控制器具有mouse事件处理逻辑。
      . 定义组件的可视化状态
      . 定义组件的组成部分。比如一个scrollbar控制器具有4部分:up arrow, down arrow, thumb, 和track。

      view-specific logic描述skin中不同组件的位置和大小,比如HScrollBar 和 VScrollBar具有不同的可视描述逻辑,决定thumb的位置。为了通知scrollbar,必须重载其逻辑。

      skinnable componen在编程和运行期间,其皮肤都可以改变。

4.组装
      . model 和 controller可以用ActionScript编写。
      . model和controller有时并不容易区分,尤其当model是UI组件时。
      . skin以MXML格式编写
      . view-specific logic可以写在skin文件中,但是绝大多数时候,logic应该放到组件中去,或者是组件的一个子类,比如ScrollBarBase->HScrollBar 或 ScrollBarBase->VScrollBar.
      . 对于skinnable组件, 通过 CSS与skins关联。

其关系如下

      左边的绿箭头表示继承关系,红箭头表示CSS转换。

5.在skins中编码 VS 在组件中编码
      通常,应该把所有的可视逻辑放在skin中,尤其是想做成可定制的。但是,这很难清楚的划分。
      view-specific logic 可以放在skin中,也可以放在组件中。
      一般来讲,在多个skin中使用的代码应放在组件中, 特定的皮肤描述应放在skin中。

      比如,scrollbar拥有position和size属性,因为对于所有的scrollbars 都需要这二个属性。因为多个skin利用view-specific logic去定位scrollbar,因此就有了HScrollBar 子类来完成这个需求。

      如果开发人员只是创建了一次性使用的组件,可以把view-specific logic放在skin文件中,而不是组件的子类中。

6.状态
      一些组件,象Button,可以在skin中使用状态。组件通过SkinState 元数据定义这些状态,并在skin中定义这些状态。

在组件中
  1. /**
  2.  * Up State of the Button
  3.  */
  4. [SkinState("up")]

  5. /**
  6.  * Over State of the Button
  7.  */
  8. [SkinState("over")]

  9. /**
  10.  * Down State of the Button
  11.  */
  12. [SkinState("down")]

  13. /**
  14.  * Disabled State of the Button
  15.  */
  16. [SkinState("disabled")]

  17. public class Button extends SkinnableComponent {
  18.     ...
  19. }
在skin中
  1. <s:Skin xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark">
  2.     <s:states>
  3.         <s:State name="up" />
  4.         <s:State name="over" />
  5.         <s:State name="down" />
  6.         <s:State name="disabled" />
  7.     </s:states>

  8.     ...
  9. </s:Skin>
      在组件中的controller 代码决定skin的状态,通过skin中的currentState属性定义当前状态。

      SkinState 元数据是一种组件在skin中定义状态的方式。如果skin没有定义需要的状态,编译器将抛出错误。

      子类可以从父类中继承SkinState,比如:
      Button声明skin states : "up", "over", "down", "disabled"。
      ToggleButton 声明skin states : "upAndSelected", "overAndSelected", "downAndSelected", "disabledAndSelected" ,并继承了Button所有的skin状态。

      一个skin的状态不必与组件的状态相同。button的currentState 不必与ButtonSkin的currentState 属性一致。button 影响skin的状态。用户通过设置组件的属性影响skin的状态,比如设置toggleButton selected=true/false。

      开发人员可以使用invalidateSkinState() 和getCurrentSkinState() 改变skin的状态, invalidateSkinState() 验证skin状态。

例如 (Button.as):
  1. package spark.components
  2. {

  3. /**
  4.  * Up State of the Button
  5.  */
  6. [SkinState("up")]

  7. /**
  8.  * Over State of the Button
  9.  */
  10. [SkinState("over")]

  11. /**
  12.  * Down State of the Button
  13.  */
  14. [SkinState("down")]

  15. /**
  16.  * Disabled State of the Button
  17.  */
  18. [SkinState("disabled")]
  19.  
  20. public class Button extends SkinnableComponent implements IFocusManagerComponent
  21. {

  22.     ...

  23.     /**
  24.      * @return Returns true when the mouse cursor is over the button.
  25.      */
  26.     public function get isHoveredOver():Boolean
  27.     {
  28.         return flags.isSet(isHoveredOverFlag);
  29.     }
  30.     
  31.     /**
  32.      * Sets the flag indicating whether the mouse cursor
  33.      * is over the button.
  34.      */
  35.     protected function setHoveredOver(value:Boolean):void
  36.     {
  37.         if (!flags.update(isHoveredOverFlag, value))
  38.             return;

  39.         invalidateSkinState();
  40.     }

  41.     ...

  42.     // GetState returns a string representation of the component's state as
  43.     // a combination of some of its public properties
  44.     protected override function getUpdatedSkinState():String
  45.     {
  46.         if (!isEnabled)
  47.             return "disabled";

  48.         if (isDown())
  49.             return "down";
  50.             
  51.         if (isHoveredOver || isMouseCaptured )
  52.             return "over";
  53.             
  54.         return "up";
  55.     }

  56.     ...

  57.     //--------------------------------------------------------------------------
  58.     //
  59.     // Event handling
  60.     //
  61.     //--------------------------------------------------------------------------
  62.     
  63.     protected function mouseEventHandler(event:Event):void
  64.     {
  65.         var mouseEvent:MouseEvent = event as MouseEvent;
  66.         switch (event.type)
  67.         {
  68.             case MouseEvent.ROLL_OVER:
  69.             {
  70.                 // if the user rolls over while holding the mouse button
  71.                 if (mouseEvent.buttonDown && !isMouseCaptured)
  72.                     return;
  73.                     setHoveredOver(true);
  74.                 break;
  75.             }

  76.             case MouseEvent.ROLL_OUT:
  77.             {
  78.                 setHoveredOver(false);
  79.                 break;
  80.             }
  81.             
  82.             ...
  83.         }
  84.     }
  85. }

  86. }

7.数据交互
      skin通过[HostComponent]元标签获取组件的引用,定义了元标签后,我们可以在编译期检查skin,以确保所有skin parts和skin state被显示。
      有两种方式使得Data和组件之间交互。一是推方法;二是拉方法。推方法意味着从组件中获取属性,并设置到skin的适当位置上。另一个方法是skin请示hostcomponent的属性值。
      拉方法是在skin和component之间使用binding。推方法是组件将值传递给skin。比如Button有个label的setter方法。我们推这个值到labelDisplay skin part。

8.Component/Skin Parts

除了skin state,Component/Skin的交互是part。
一些组件由独立的part构成,一个NumericStepper包含一个up button,donw button和text。
有两个类型的part:static和dynamic。Static parts由skin自动实例化,static part仅有一个实例。Dynamic part需要时实例化,存在多个实例,以scrollbar为例,有四个皮肤parts:增加按钮,减少按钮,轨迹带和滚动条。

定义组件上的skin part
[SkinPart]用于声明part。元标签可用于任何public属性。属性的名字变成了part的一部分。这有个例子,skin part定义了"thumb",作为Button的属性。
[SkinPart(required="true")]
public var thumb:Button;

[SkinPart]元标签的静态part有一个可选属性:required。如果设置required="true",必须确保该part为非null。

这有个非必须skin part的例子
[SkinPart(required="false")]
public var upButton:Button;

当一个组件需要一个或更多的part实例。比如Accordion 需要创建多个导航头。动态part可以在[SkinPart]中定义,但是变量类型必须是IFactory。
这里有一个例子,工厂创建spark.components.Button类型的实例。Dynamic parts也是可选的。
[SkinPart(type="spark.components.Button")]
public var headerFactory:IFactory;

9.定义skin中的skin part
下面是一个包含thumb part的例子

点击(此处)折叠或打开

  1. <s:Skin xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:local="*">
  2.     <!-- other stuff here... -->

  3.     <!-- "thumb" 在此定义. MyCustomThumb"类的实例,Button的子类, 属性id用于绑定组件part元素 -->
  4.     <local:MyCustomThumb id="thumb" ... />

  5.     <!-- other stuff here... -->
  6. </s:Skin>
      skin part可以在skin文件中任何地方定义。如果没有定义,在组件皮肤渲染时将抛出运行时错误。如果HostComponent 元标签在skin中定义了,将抛出编译错误。
      动态part,应该在skin文件中的Declarations 部分。Declarations 是MXML的一部分,下面是一个skin包含动态par "theaderFactory"的例子。

点击(此处)折叠或打开

  1. <s:Skin xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:local="*">
  2.     <fx:Declarations>
  3.         <fx:Component id="headerFactory">
  4.             <local:MyCustomHeaderControl />
  5.         </fx:Component >

  6.         <!-- More dynamic part definitions can go here... -->
  7.     </fx:Declarations>

  8.     <!-- Static skin elements and parts go here... -->
  9. </s:Skin>

10.static part运行
      当加载一个包含static part的skin,SkinnableComponent 基类将将所有皮肤中的static part分配给组件声明的part变量上。一旦分配完成,组件将仅直接引用实例变量。
      当变量被分配后,partAdded()函数被调用。在skin被卸载时,partRemoved()函数被调用。
      下面是一个简单的例子。

点击(此处)折叠或打开

  1. override protected function partAdded(partName:String, instance:*):void
  2. {
  3.     super.partAdded(partName, instance);
  4.     
  5.     // For static parts we can just compare the instance with the property
  6.     if (instance == thumb)
  7.         thumb.addEventListener(...);
  8. }

  9. override protected function partRemoved(partName:String, instance:*):void
  10. {
  11.     super.partRemoved(partName, instance);
  12.     
  13.     if (instance == thumb)
  14.         thumb.removeEventListener(...);
  15. }

11.dynamic part运行
      使用createDynamicPartInstance()创建的动态part实例,使用removeDynamicPartInstance()移除。当一个动态part被add/remove,方法partAdded()和 partRemoved()被调用。
      下面是一个使用动态part "separator"的例子

点击(此处)折叠或打开

  1. public class MyComponent extends SkinnableComponent
  2. {
  3.     /**
  4.      * Declare the "separator" part
  5.      */
  6.     [SkinPart(type="flash.display.DisplayObject")]
  7.     public var separator:IFactory;

  8.     protected const SEPARATOR_NAME:String = "separator";

  9.     ...

  10.     protected function createSeparator():void
  11.     {
  12.         var separator:DisplayObject = createPartInstance(SEPARATOR_NAME);
  13.         
  14.         separator.alpha = Math.random();

  15.         separators[i] = separator;
  16.         skin.addElement(separator);
  17.     }
  18.   
  19.     override protected function partAdded(partName:String, instance:*):void
  20.     {
  21.         super.partAdded(partName, instance);

  22.         if (partName == SEPARATOR_NAME)
  23.         {
  24.             // A new separator has been created.
  25.             
  26.             // Add event listeners
  27.             instance.addEventListener(...);
  28.         }
  29.     }

  30.     override protected function partRemoved(partName:String, instance:*):void
  31.     {
  32.         super.partRemoved(partName, instance);

  33.         if (partName == SEPARATOR_NAME)
  34.         {
  35.             // A separator is being removed


  36.             // Remove event listeners
  37.             instance.removeEventListener(...);
  38.         }
  39.     }
  40.     }
  41. }

      createSeparator()根据skin的dynamic part创建了一个separator ,并设置了一个随机的alpha值。createSeparator()调用了createDynamicPartInstance(),这将自动调用partAdded()。

      但是,如果你想在新的skin中创建dynamic part,一旦skin加载,你必须再一次创建他们。不能自动创建的原因是每个动态part都有状态。
      如果你想在最新加载的skin中做些事情,则调用super.attachSkin()。卸载skin则调用detachSkin()。

点击(此处)折叠或打开

  1. public class MyComponent extends SkinnableComponent
  2. {
  3.     /**
  4.      * Declare the "separator" part
  5.      */
  6.     [SkinPart(type="flash.display.DisplayObject")]
  7.     public var separator:IFactory;

  8.     protected const SEPARATOR_NAME:String = "separator";

  9.     ...

  10.     protected function createSeparator():void
  11.     {
  12.         var separator:DisplayObject = createPartInstance(SEPARATOR_NAME);
  13.         
  14.         separator.alpha = Math.random();

  15.         separators.push(separator);
  16.         skin.addElement(separator);
  17.     }
  18.   
  19.     override protected function partAdded(partName:String, instance:*):void
  20.     {
  21.         super.partAdded(partName, instance);

  22.         if (partName == SEPARATOR_NAME)
  23.         {
  24.             // A new separator has been created.
  25.             
  26.             // Add event listeners
  27.             instance.addEventListener(...);
  28.         }
  29.     }

  30.     override protected function partRemoved(partName:String, instance:*):void
  31.     {
  32.         super.partRemoved(partName, instance);

  33.         if (partName == SEPARATOR_NAME)
  34.         {
  35.             // A separator is being removed


  36.             // Remove event listeners
  37.             instance.removeEventListener(...);
  38.         }
  39.     }
  40.     
  41.     override protected function detachSkin():void
  42.     {
  43.         for (var i:int = 0; i < separators.length; i++)
  44.     {
  45.      separatorAlphas[i] = separators[i].alpha;
  46.         }

  47.         separators = [];

  48.         super.detachSkin();
  49.     }

  50.     override protected function attachSkin():void
  51.     {
  52.         super.attachSkin();
  53.         
  54.         // create separators from last time
  55.         
  56.         for (var i:int = 0; i < separatorAlphas.length; i++)

  57.     {
  58.      var separator:DisplayObject = createPartInstance(SEPARATOR_NAME);
  59.     
  60.      separator.alpha = separatorAlphas[i];
  61.     
  62.      separators.push(separator);
  63.      skin.addElement(separator);
  64.         }
  65.     }
  66.     }
  67. }

12. style
      皮肤定义了组件的可视部分。皮肤与style的交互,可以有两种方法:binding和重载updateDisplayList()。

Binding 例子

点击(此处)折叠或打开

  1. <s:Skin xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark"
  2.              minWidth="21" minHeight="21" alpha.disabled="0.5">
  3.     
  4.     <fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
  5.     
  6.     <!-- states -->
  7.     <s:states>
  8.         <s:State name="up" />
  9.         <s:State name="over" />
  10.         <s:State name="down" />
  11.         <s:State name="disabled" />
  12.     </s:states>
  13.     
  14.     <s:Rect id="fill" left="1" right="1" top="1" bottom="1" radiusX="{getStyle('cornerRadius')}">
  15.         <s:fill>
  16.             <s:LinearGradient rotation="90">
  17.                 <s:GradientEntry color="0xFFFFFF"
  18.                                  color.over="0xBBBDBD"
  19.                                  color.down="0xAAAAAA"
  20.                                  alpha="0.85" />
  21.                 <s:GradientEntry color="0xD8D8D8"
  22.                                  color.over="0x9FA0A1"
  23.                                  color.down="0x929496"
  24.                                  alpha="0.85" />
  25.             </s:LinearGradient>
  26.         </s:fill>
  27.     </s:Rect>

  28.     
  29.     <s:Label id="labelDisplay"
  30.              textAlign="center"
  31.              verticalAlign="middle"
  32.              maxDisplayedLines="1"
  33.              horizontalCenter="0" verticalCenter="1"
  34.              left="10" right="10" top="2" bottom="2" />
  35.     
  36. </s:Skin>

updateDisplayList()例子如下

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Skin xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark"
  3.              minWidth="21" minHeight="21" alpha.disabled="0.5">
  4.     
  5.     <fx:Metadata>[HostComponent("spark.components.Button")]</fx:Metadata>
  6.     
  7.     <fx:Script>
  8.         <![CDATA[
  9.             override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
  10.             {
  11.                 fill.radiusX = getStyle('cornerRadius');
  12.                 
  13.                 super.updateDisplayList(unscaledWidth, unscaledHeight);
  14.             }
  15.         ]]>
  16.     </fx:Script>
  17.     
  18.     <!-- states -->
  19.     <s:states>
  20.         <s:State name="up" />
  21.         <s:State name="over" />
  22.         <s:State name="down" />
  23.         <s:State name="disabled" />
  24.     </s:states>
  25.     
  26.     <s:Rect id="fill" left="1" right="1" top="1" bottom="1">
  27.         <s:fill>
  28.             <s:LinearGradient rotation="90">
  29.                 <s:GradientEntry color="0xFFFFFF"
  30.                                  color.over="0xBBBDBD"
  31.                                  color.down="0xAAAAAA"
  32.                                  alpha="0.85" />
  33.                 <s:GradientEntry color="0xD8D8D8"
  34.                                  color.over="0x9FA0A1"
  35.                                  color.down="0x929496"
  36.                                  alpha="0.85" />
  37.             </s:LinearGradient>
  38.         </s:fill>
  39.     </s:Rect>

  40.     
  41.     <s:Label id="labelDisplay"
  42.              textAlign="center"
  43.              verticalAlign="middle"
  44.              maxDisplayedLines="1"
  45.              horizontalCenter="0" verticalCenter="1"
  46.              left="10" right="10" top="2" bottom="2" />
  47.     
  48. </s:Skin>
下面在style中定义属性cornerRadius

点击(此处)折叠或打开

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="" xmlns:s="library://ns.adobe.com/flex/spark">
  3.     <fx:Style>
  4.         @namespace s "library://ns.adobe.com/flex/spark";
  5.         
  6.         s|Button
  7.         {
  8.             cornerRadius: 10;
  9.         }
  10.     </fx:Style>
  11.     <s:Button skinClass="GradientSkin" label="hello" />
  12. </s:Application>
也可以在mxml中内置style,直接在组件中声明style元标签。比如

点击(此处)折叠或打开

  1. [Style(name="cornerRadius", type="Number", format="Length", inherit="no", minValue="0.0")]
  2. public class Button extends SkinnableComponent
  3. {
  4. ...
  5. }

13 API

点击(此处)折叠或打开

  1. SkinnableComponent:

  2. package spark.components.supportClasses
  3. {

  4. /**
  5.  * Name of the skin to use for this component. The skin must be a class that extends
  6.  * the flex.core.Skin class.
  7.  */
  8. [Style(name="skinClass", type="Class")]

  9. public class SkinnableComponent extends UIComponent
  10. {

  11.     //--------------------------------------------------------------------------
  12.     //
  13.     // Properties
  14.     //
  15.     //--------------------------------------------------------------------------

  16.     /**
  17.      * The instance of the skin class for this component instance.
  18.      * This is a read-only property that gets set automomatically when Flex
  19.      * calls the attachSkin() method.
  20.      */
  21.     public function get skin():UIComponent;


  22.     //--------------------------------------------------------------------------
  23.     //
  24.     // Methods - Skin/Behavior lifecycle
  25.     //
  26.     //--------------------------------------------------------------------------

  27.     /**
  28.      * Create the skin for the component.
  29.      * You do not call this method directly.
  30.      * Flex calls it automatically when it calls createChildren() or
  31.      * the UIComponent.commitProperties() method.
  32.      * Typically, a subclass of SkinnableComponent does not override this method.
  33.      *
  34.      *

    This method instantiates the skin for the component,

  35.      * adds the skin as a child of the component, and
  36.      * resolves all part associations for the skin


  37.      */
  38.     protected function attachSkin():void;

  39.     /**
  40.      * Destroys and removes the skin for this component.
  41.      * You do not call this method directly.
  42.      * Flex calls it automatically when a skin is changed at runtime.
  43.      *
  44.      * This method removes the skin and clears all part associations.
  45.      *
  46.      *

    Typically, subclasses of SkinnableComponent do not override this method.


  47.      */
  48.     protected function detachSkin():void;

  49.     /**
  50.      * Find the skin parts in the skin class and assign them to the properties of the component.
  51.      * You do not call this method directly.
  52.      * Flex calls it automatically when it calls the attachSkin() method.
  53.      * Typically, a subclass of SkinnableComponent does not override this method.
  54.      */
  55.     protected function findSkinParts():void;

  56.     /**
  57.      * Clear out references to skin parts.
  58.      * You do not call this method directly.
  59.      * Flex calls it automatically when it calls the detachSkin() method.
  60.      *
  61.      *

    Typically, subclasses of SkinnableComponent do not override this method.


  62.      */
  63.     protected function clearSkinParts():void;

  64.     //--------------------------------------------------------------------------
  65.     //
  66.     // Methods - Parts
  67.     //
  68.     //--------------------------------------------------------------------------

  69.     /**
  70.      * Called when a skin part is added.
  71.      * You do not call this method directly.
  72.      * For static parts, Flex calls it automatically when it calls the attachSkin() method.
  73.      * For dynamic parts, Flex calls it automatically when it calls
  74.      * the createDynamicPartInstance() method.
  75.      *
  76.      *

    Override this function to attach behavior to the part.

  77.      * If you want to override behavior on a skin part that is inherited from a base class,
  78.      * do not call the super.partAdded() method.
  79.      * Otherwise, you should always call the super.partAdded() method.


  80.      *
  81.      * @param partname The name of the part.
  82.      *
  83.      * @param instance The instance of the part.
  84.      */
  85.     protected function partAdded(partName:String, instance:Object):void;

  86.     /**
  87.      * Called when an instance of a skin part is being removed.
  88.      * You do not call this method directly.
  89.      * For static parts, Flex calls it automatically when it calls the detachSkin() method.
  90.      * For dynamic parts, Flex calls it automatically when it calls
  91.      * the removeDynamicPartInstance() method.
  92.      *
  93.      *

    Override this function to remove behavior from the part.


  94.      *
  95.      * @param partname The name of the part.
  96.      *
  97.      * @param instance The instance of the part.
  98.      */
  99.     protected function partRemoved(partName:String, instance:Object):void;


  100.     //--------------------------------------------------------------------------
  101.     //
  102.     // Methods - Dynamic Parts
  103.     //
  104.     //--------------------------------------------------------------------------
  105.     /**
  106.      * Create an instance of a dynamic skin part.
  107.      * Dynamic skin parts should always be instantiated by this method,
  108.      * rather than directly by calling the newInstance() method on the factory.
  109.      * This method creates the part, but does not add it to the display list.
  110.      * The component must call the Group.addElement() method, or the appropriate
  111.      * method to add the skin part to the display list.
  112.      *
  113.      * @param partName The name of the part.
  114.      *
  115.      * @return The instance of the part, or null if it cannot create the part.
  116.      */
  117.     protected function createDynamicPartInstance(partName:String):Object;

  118.     /**
  119.      * Remove an instance of a dynamic part.
  120.      * You must call this method before a dynamic part is deleted.
  121.      * This method does not remove the part from the display list.
  122.      *
  123.      * @param partname The name of the part.
  124.      *
  125.      * @param instance The instance of the part.
  126.      */
  127.     protected function removeDynamicPartInstance(partName:String, instance:Object):void;

  128.     /**
  129.      * Returns the number of instances of a dynamic part.
  130.      *
  131.      * @param partName The name of the dynamic part.
  132.      *
  133.      * @return The number of instances of the dynamic part.
  134.      */
  135.     protected function numDynamicParts(partName:String):int;

  136.     /**
  137.      * Returns a specific instance of a dynamic part.
  138.      *
  139.      * @param partName The name of the dynamic part.
  140.      *
  141.      * @param index The index of the dynamic part.
  142.      *
  143.      * @return The instance of the part, or null if it the part does not exist.
  144.      */
  145.     protected function getDynamicPartAt(partName:String, index:int):Object;


  146.     //--------------------------------------------------------------------------
  147.     //
  148.     // Skin states support
  149.     //
  150.     //--------------------------------------------------------------------------

  151.     /**
  152.      * Returns the name of the state to be applied to the skin. For example, a
  153.      * Button component could return the String "up", "down", "over", or "disabled"
  154.      * to specify the state.
  155.      *
  156.      *

    A subclass of SkinnableComponent must override this method to return a value.


  157.      *
  158.      * @return A string specifying the name of the state to apply to the skin.
  159.      */
  160.     protected function getCurrentSkinState():String;

  161.     /**
  162.      * Marks the component so that the new state of the skin is set
  163.      * during a later screen update.
  164.      */
  165.     public function invalidateSkinState():void;
  166. }
  167. }






参考文献
1.Spark Skinning (including SkinnableComponent) - Functional and Design Specification. http://www.cnblogs.com/fxair/archive/2010/05/25/1743638.html
2.
阅读(3222) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~