免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1671 | 回复: 0

FLEX皮肤_皮肤原理 [复制链接]

论坛徽章:
0
发表于 2011-12-23 03:44 |显示全部楼层
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="http://ns.adobe.com/mxml/2009" 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. }

待续


参考文献
1.Spark Skinning (including SkinnableComponent) - Functional and Design Specification. http://opensource.adobe.com/wiki/display/flexsdk/Spark+Skinning
2.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2021中国系统架构师大会

【数字转型 架构重塑】2021年5月20日-22日第十三届中国系统架构师大会将在云端进行网络直播。

大会为期3天的议程,涉及20+专场,近120个主题,完整迁移到线上进行网络直播对会议组织来说绝非易事;但考虑到云端会议的直播形式可以实现全国各地技术爱好者的参与,也使ITPUB作为技术共享交流平台得到更好的普及,我们决定迎难而上。
http://sacc.it168.com/


大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP