播放头前进到第二桢,docFrameHandler 函数开始执行。
首先会执行很多Singleton.registerClass方法,然后执行有[Mixin]元标签的类的
public static function init(fbs:IFlexModuleFactory):void 方法
Flex编译器编译时会生成很多 有[Mixin]元标签的类 其中大部分类都与样式有关,象下面这些

 
程序代码
"_alertButtonStyleStyle", "_ScrollBarStyle",
"_activeTabStyleStyle", "_textAreaHScrollBarStyleStyle",
"_ToolTipStyle", "_advancedDataGridStylesStyle",
"_comboDropdownStyle", "_comboDropDownStyle",
"_ContainerStyle", "_textAreaVScrollBarStyleStyle",
"_linkButtonStyleStyle", "_globalStyle", "_windowStatusStyle",
"_windowStylesStyle", "_activeButtonStyleStyle",
"_errorTipStyle", "_richTextEditorTextAreaStyleStyle",
"_CursorManagerStyle", "_todayStyleStyle", "_dateFieldPopupStyle",
"_plainStyle", "_dataGridStylesStyle", "_ApplicationStyle",
"_headerDateTextStyle", "_ButtonStyle", "_VScrollBarStyle",
"_popUpMenuStyle", "_swatchPanelTextFieldStyle",
"_opaquePanelStyle", "_weekDayStyleStyle", "_headerDragProxyStyleStyle"


类,他们的作用就是把样式信息注册到 StyleManager,这样在生成组件的时候组件能得到自己的样式信息。

在flex builder 安装目录下的 sdks/3.0.0/frameworks/libs 目录有一个framework.swc 文件,你用Winrar 打开会看到 defaults.css这个文件。Defaults.css文件定义了flex组件的默认样式,这里的每一个css选择符(selector)就对应上面的一个类。其实上面的那些类是flex编译器按照这个defaults.css 文件在编译时自动生成的。
下面就是其生成的_ButtonStyle 类:


 
程序代码

package
{

import flash.display.Sprite;
import mx.core.IFlexModuleFactory;
import mx.core.mx_internal;
import mx.styles.CSSStyleDeclaration;
import mx.styles.StyleManager;
import mx.skins.halo.ButtonSkin;

[ExcludeClass]

public class _ButtonStyle
{

public static function init(fbs:IFlexModuleFactory):void
    {
        var style:CSSStyleDeclaration = StyleManager.getStyleDeclaration("Button");
    
        if (!style)
        {
            style = new CSSStyleDeclaration();
            StyleManager.setStyleDeclaration("Button", style, false);
        }
    
        if (style.defaultFactory == null)
        {
            style.defaultFactory = function():void
            {
                this.paddingTop = 2;
                this.textAlign = "center";
                this.skin = mx.skins.halo.ButtonSkin;
                this.paddingLeft = 10;
                this.fontWeight = "bold";
                this.cornerRadius = 4;
                this.paddingRight = 10;
                this.verticalGap = 2;
                this.horizontalGap = 2;
                this.paddingBottom = 2;
            };
        }
    }
}

}


看完了就明白了吧,也就是说当这些类的  init(fbs:IFlexModuleFactory)方法执行完后,我们就可以通过    StyleManager.getStyleDeclaration(selector:String):CSSStyleDeclaration  方法获得在 defaluts.css文件中定义的样式信息。

需要注意的是如果你在编译时添加了其他的主题,那么主题的样式会覆盖 defaluts.css文件中的样式。
假如你的主题 中定义了


 
程序代码
Button
{
    cornerRadius: 8;
}


那么你的 _ButtonStyle类中的 this.cornerRadius = 8; 而不是 this.cornerRadius = 4;
当然你在主题中添加的新的css选择符在编译时也会生成相对应的类。比如你在主题中增加了
程序代码
.flashshe
{
    color: #ff0000;
}


那么编译器编译时会生成一个
程序代码
package { import flash.display.Sprite; import mx.core.IFlexModuleFactory; import mx.core.mx_internal; import mx.styles.CSSStyleDeclaration; import mx.styles.StyleManager; [ExcludeClass] public class _FlashsheStyle { public static function init(fbs:IFlexModuleFactory):void { var style:CSSStyleDeclaration = StyleManager.getStyleDeclaration(".flashshe"); if (!style) { style = new CSSStyleDeclaration(); StyleManager.setStyleDeclaration(".flashshe", style, false); } if (style.defaultFactory == null) { style.defaultFactory = function():void { this.color = 0xff0000; }; } } } }


类。在执行 Main.mxml (假设我们的Flex工程的主文件为Main.mxml)类的构造函数时会调用StyleManager.mx_internal::initProtoChainRoots();方法,执行完后 StyleManager.stylesRoot属性 指向一个 Object,通过这个 Object我们就可以访问到defaults.css文件中Global css 选择符定义的样式信息,如果你的Global css 选择符中定义了  color: #0B333C;   那么StyleManager.stylesRoot[color]的值就为 0x0B333C。(注意这些都是 flex框架的内部方法,所以你不要尝试去访问,大部分情况下如果你访问的话编译器会报错,即使能访问,也不要去做)

当我们在flex中调用 addChild(child)的时候,其中包含了下面几步:

程序代码
addingChild(child);
$addChildAt(child, index);
childAdded(child);


看如下一个mxml文件:
程序代码

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" xmlns:ns1="*">
    
    <mx:Style source="one.css"/>
    <mx:Style>
        .myBtn
        {
            color: #00ff00;
            fontSize: 14;    
        }
    </mx:Style>
    <!--  MyButton 组件 从 Button 继承 -->
    <ns1:MyButton id="testBtn" x="27" y="200" color="#0000ff" styleName="myBtn"/>
    
</mx:Application>

程序代码

/* one.css */

Button
{
    color: #ff0000;
}

MyButton
{
    fontWeight: 16;
}


当生成 MyButton 时 过程如下:
首先调用 addingChild(testBtn), 在这个方法里面
1,获得 Global css 选择符中定义的样式的一份拷贝(通过 StyleManager.stylesRoot);
2,查找 Button css 选择符,将里面的样式添加到global拷贝中,同名的样式就覆盖;
3,查找 MyButton css 选择符,将里面的样式添加到global拷贝中,同名的样式就覆盖;
查找完type selector后开始查找class selector
4, 查找 .myBtn css 选择符,将里面的样式添加到global拷贝中,同名的样式就覆盖;
查找完 class selector 后开始查找inline style
4,将 color="#0000ff" 样式添加到global拷贝中,同名的样式就覆盖;

最后将这些样式信息存储到 UIComponent的inheritingStyles 和 nonInheritingStyles 属性中。这样调用UIComponent.getStyle(styleProp:String):* 就可以得到正确的样式值了。

Flex框架通过这种方式,我们就可以在组件创建过程中得到组件的样式信息,方便我们在createChildren(),commitProperties(),layoutChrome(),measure(),updateDisplayList()方法中访问。在组件的构造函数中就不要使用 UIComponent.getStyle(styleProp:String):* 方法,因为你调用getStyle方法返回的是null。样式信息是用来渲染组件用的,所以没有必要在构造函数中使用。

每当组件需要重新设置自己的样式时(比如说调用了setStyle()方法或者设置了styleName属性),组件的styleChanged(styleProp:String)方法就会被调用,然后我们在styleChanged(styleProp:String)方法体里面根据参数styleProp的值的不同来对组件的样式做出相应的处理。那么什么时候组件的styleChanged(styleProp:String)方法会触发呢?下面介绍如下:

1,setStyle()方法
当我们调用setStyle()方法的时候,首先会调用该组件的styleChanged(styleProp)然后判断改变的样式是否是可继承样式,如果是,则调用该组件的所有子孙的styleChanged(styleProp)方法。比如:

程序代码
<mx:Canvas id="myCanvas">
    <mx:Vbox id="box" x="0" y="10" width="200">
        <mx:Label id="text1" text="@Resource(key='name', bundle='test')" color="#ff0000"/>
        <mx:Label id="text2" text="@Resource(key='age', bundle='test')" styleName="ageLabel"/>
        <mx:Label id="text3" text="@Resource(key='sex', bundle='test')"/>
        <mx:Label id="text4" text="{resourceManager.getString('test', 'sex')}"/>
    </mx:Vbox>
    <mx:Button id="myBtn" x="27" y="100" label="change" click="changeHandler(event)"/>    
</mx:Canvas>  


当我们调用 myCanvas.setStyle("color", 0xff0000)的时候,首先会重新设置该组件的样式缓存(CSS style cache),
这样调用myCanvas.getStyle("color")时就能得到值0xff0000。然后调用myCanvas.styleChanged("color"); 因为
color是可继承样式,所以会接着调用box.styleChanged("color"),text1.styleChanged("color"),text2.styleChanged("color"),text3.styleChanged("color"),text4.styleChanged("color"),myBtn.styleChanged("color");
当我们调用 myCanvas.setStyle("backgroundColor", 0xff0000)的时候,首先调用myCanvas.styleChanged("backgroundColor")因为backgroundColor不是可继承样式,所以myCanvas的子孙的styleChanged(styleProp)方法不会被调用。

2. addChild(chlid)的时候
当我们使用addChild(chlid)时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged(null) 和chlid的子孙的styleChanged(null)方法。

3, 设置 styleName
当我们给一个组件(比如实例名是child)设置styleName属性时,首先会重新设置该组件和该组件的子孙的样式缓存,然后调用chlid.styleChanged("styleName")和chlid的子孙的styleChanged("styleName")方法。

4, 运行时载入样式表单
运行时载入样式表单我们通常会使用StyleManager.loadStyleDeclarations(url:String, update:Boolean = true, trustContent:Boolean = false, applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null)方法。当把参数update设置为true时表示样式表单载入完成后马上更新样式。其原理是:样式表单载入完成后程序中的所有组件会重新设置组件的样式缓存,并调用组件的styleChanged(null)方法。

当我们建立一个ActionScript自定义组件(ActionScript Custom Components),并且该组件支持自定义样式的时候,我们的组件类里面必须要有一个


 
程序代码
override public function styleChanged(styleProp:String):void
{
    // 方法体
}

方法。为什么呢?应为如果没有这个方法,你怎么来检测你的样式的改变呢?
通过我上面的分析,相信你一定能设计出一个出色的适应Flex框架的支持自定义样式的组件。关于“自定义组件支持自定义样式”你可以参考Flex帮助文档里面的 ActionScript Custom Components / Custom Style Properties 一节。

下面是 UIComponent 组件里面的styleChanged(styleProp:String):void方法的定义,和本文无关,只是方便我自己查阅而放在这里。

程序代码
/** * Detects changes to style properties. When any style property is set, * Flex calls the <code>styleChanged()</code> method, * passing to it the name of the style being set. * * <p>This is an advanced method that you might override * when creating a subclass of UIComponent. When you create a custom component, * you can override the <code>styleChanged()</code> method * to check the style name passed to it, and handle the change accordingly. * This lets you override the default behavior of an existing style, * or add your own custom style properties.</p> * * <p>If you handle the style property, your override of * the <code>styleChanged()</code> method should call the * <code>invalidateDisplayList()</code> method to cause Flex to execute * the component's <code>updateDisplayList()</code> method at the next screen update.</p> * * @param styleProp The name of the style property, or null if all styles for this * component have changed. */ public function styleChanged(styleProp:String):void { // If font changed, then invalidateProperties so // we can re-create the text field in commitProperties if (this is IFontContextComponent && hasFontContextChanged()) invalidateProperties(); // Check to see if this is one of the style properties // that is known to affect layout. If (!styleProp || styleProp == "styleName" || StyleManager.isSizeInvalidatingStyle(styleProp)) { // This style property change may affect the layout of this // object. Signal the LayoutManager to re-measure the object. invalidateSize(); } if (!styleProp || styleProp == "styleName" || styleProp == "themeColor") { initThemeColor(); } invalidateDisplayList(); if (parent is Iinvalidating) { if (StyleManager.isParentSizeInvalidatingStyle(styleProp)) Iinvalidating(parent).invalidateSize(); if (StyleManager.isParentDisplayListInvalidatingStyle(styleProp)) Iinvalidating(parent).invalidateDisplayList(); } }

转载于:https://www.cnblogs.com/hainange/archive/2009/09/22/6153071.html

Flex样式工作原理相关推荐

  1. 前端必读:浏览器内部工作原理

    前端必读:浏览器内部工作原理 作者: Tali Garsiel  发布时间: 2012-02-09 14:32  阅读: 2133 次  原文链接   全屏阅读  [收藏]   http://kb.c ...

  2. 现代浏览器的工作原理

    英文原文:Tali Garsiel,编译:zzzaquarius 简介 浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工 作原理,我们将看到,从你在地址栏输入google.com到你看到goo ...

  3. 【转载】现代浏览器的工作原理

    原文:http://taligarsiel.com/Projects/howbrowserswork1.htm 编译:zzzaquarius  http://blog.jobbole.com/1274 ...

  4. IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/中后台/体验管理等)之详细攻略

    IT:前端进阶技术路线图(初级→中级→高级)之初级(研发工具/HTML/CSS/JS/浏览器)/中级(研发链路/工程化/库/框架/性能优化/工作原理)/高级(搭建/Node/IDE/中后台/体验管理/ ...

  5. javascript教程系列20: 前端必读,浏览器内部工作原理(转)

    目录 一.介绍 二.渲染引擎 三.解析与DOM树构建 四.渲染树构建 五.布局 六.绘制 七.动态变化 八.渲染引擎的线程 九.CSS2可视模型 英文原文:How Browsers Work: Beh ...

  6. 浏览器工作原理探究详解

    浏览器工作原理探究 标签: 浏览器工作原理 / web性能优化 引言 最近对web的性能优化比较感兴趣,而前端代码主要在浏览器工作的.如果对浏览器的工作原理了解清楚,可以为web性能优化提供方向以及理 ...

  7. 干货:浏览器渲染引擎Webkit和V8引擎工作原理

    浏览器的历史 W3C在80年代后期90年代初期发明了世界上第一个浏览器WorldWideWeb(后更名为Nexus),支持文本/简单的样式表/电影/声音和图片 1993年,网景(netscape)浏览 ...

  8. How browsers work -Behind the scenes of modern web browsers 浏览器到底是怎么工作的、浏览器的工作原理(完整中文翻译)

    How browsers work -Behind the scenes of modern web browsers 有空翻译一下这篇必读的文章 -浏览器到底是怎么工作的.浏览器的底层原理是啥.浏览 ...

  9. 前端文摘:深入解析浏览器的幕后工作原理(转)

    前端文摘:深入解析浏览器的幕后工作原理 https://www.cnblogs.com/lhb25/p/how-browsers-work.html 您可能感兴趣的相关文章 10大流行 Metro U ...

最新文章

  1. Uber无人车撞人视频公布,究竟哪儿出问题了?
  2. 第十五届全国大学生智能汽车竞赛 信标组亮灯顺序和次数
  3. 对于非阻塞socket的可写事件
  4. 关于.framework 文件过大 移除包内对i386 x86_64 的支持
  5. Vue指令之v-model和双向数据绑定
  6. 爬虫批量下载全站小说并自动保存
  7. SAP C4C和Gigya(Customer Data Cloud)的客户报表
  8. SQLSERVER中RANK OVER(PARTITION BY)的用法
  9. mysql hibernate 延迟_在mysql数据库中,hibernate一对多的集合的延迟加载无效
  10. 转:百度手机地图网络性能优化实践
  11. Linux vim常用命令
  12. 面试java回答优缺点_面试时被问“你有什么优缺点”应该怎么回答?
  13. 当我们在谈论高并发的时候究竟在谈什么?
  14. 06.输入系统:第10课第20节_输入系统_多点触摸_电容屏驱动程序
  15. 阿里IOT云平台(二)---10分钟物联网设备接入阿里云IoT平台
  16. 使用hutool的导出Excel后缀xlsx
  17. 小猴吃桃matlab,小班美术优质课教案及教学反思《小猴吃桃》
  18. 满意度调查中的NPS题目怎么设置?
  19. 人脸表情数据集-fer2013
  20. js实现时间每秒更新

热门文章

  1. 使用ros2d.js实现web端导航
  2. Android运行时权限,设置帮助类BaseActivity;电话权限,短信权限,
  3. RandomAccessFile 随机存取文件任意位置数据
  4. 安装Linux系统后无法启动win,安装Win10 CentOS7双系统后无法启动Win10系统怎么办
  5. 如何用c++画图_画图教室 | 绘制Mapping第一步:美团搜索火锅串串香...认真的!...
  6. 3D旋转(CSS3)
  7. PTA—计算摄氏温度(C语言)
  8. Angular 自定义loading组件
  9. python之计算空间向量夹角
  10. opencv之对图像中的点做几何变换