Adobe Air & Adobe Flex & ActionScript & Mobile Dev & HTML5 & RIA & User Experience
Flex Builder/Flash Builder/FDT Profile概要分析打不开解决方法:
这样你就可以打开Flex Builder/Flash Builder/FDT Profile进行相应的概要分析。
适用于最新的Flash Builder4.5。
Flex 的 Style 檔案可以編入 Application 也可以單獨編譯成 SWF 檔案
可是假如將 Style 檔案放在 Package Folder 之下,且檔案內的 CSS 有用到 Class Reference
那麼編譯就會出現 Error

這樣還挺不方便的,強迫一定要將 Style 放在 src 之下才行
為了改善這問題,觀察 Flex Style 產生的 AS3 檔案
發現原來它也是繼承 ModuleBase 且實作 IStyleModule 介面
所以獨立 Style 最後就是變成一個 Module
既然這樣何不自己寫一個 Style Module 呢?
嘗試過幾次之後,發現 Flex 產生的 Style Module 是有包含復原機制的
會自動產生 selectors, overrideMap, effectMap 等資訊
等到要卸載 Style Module 時,它會用這些資訊將 App Style 還原
可是假如只是一般的 Module + Style 就沒有這些東西
平鋪直敘的一行一行呼叫 StyleManager 設定好 Style
這些動作都是 Flex Compiler 自動產生的,執行過了就沒了,很難加以干預
最後想到一個很特殊的技巧,在自訂的 StyleModule 內宣告一個 StyleManager 變數成員
當作是一個 Hook 鉤子,因為它的名稱與 Flex 靜態類別 mx.styles.StyleManager 名稱重覆
所以程式碼內取用 StyleManager 時,會優先取到 StyleManager 變數成員
這樣一來所有對 StyleManager 設定 Style 動作都可以欄截下來了
protected var StyleManager:Object = {styleModule: this, getStyleManager: function(... args):* { return new StyleManagerProxy(this.styleModule); }};
只要再補上一個 StyleManagerProxy 類別就好
用來將收到的 Style Declaration 全部轉丟回去給自訂 StyleModule
package com.ticore.style.module { import mx.managers.SystemManagerGlobals; import mx.styles.CSSStyleDeclaration; import mx.styles.StyleManagerImpl; public class StyleManagerProxy extends StyleManagerImpl { protected var styleModule:Object; override public function StyleManagerProxy(styleModule:Object) { super(SystemManagerGlobals.topLevelSystemManagers[0]); this.styleModule = styleModule; } override public function getStyleDeclaration(selector:String):CSSStyleDeclaration { return null; } override public function setStyleDeclaration(selector:String, styleDeclaration:CSSStyleDeclaration, update:Boolean):void { styleModule.pushStyle(styleDeclaration); } } }
至於其它 Style Module 部分直接從 Flex 產生的版本抄就好了
以下便是完整的自訂 StyleModule:
package com.ticore.style.module { import flash.system.Security; import mx.core.mx_internal; import mx.modules.ModuleBase; import mx.styles.CSSCondition; import mx.styles.CSSSelector; import mx.styles.CSSStyleDeclaration; import mx.styles.IStyleManager2; import mx.styles.IStyleModule; public class StyleModule extends ModuleBase implements IStyleModule { private static var domainsAllowed:Boolean = allowDomains(); private static function allowDomains():Boolean { if (Security.sandboxType != "application") { Security.allowDomain("*"); } return true; } //============================================================ protected var selectors:Array = []; protected var overrideMap:Object = {}; protected var effectMap:Object = {}; protected var unloadGlobal:Boolean; protected var styleManager:IStyleManager2; //============================================================ public static var StyleManagerCls:Class = mx.styles.StyleManager; // StyleManager class reference hook protected var StyleManager:Object = {styleModule: this, getStyleManager: function(... args):* { return new StyleManagerProxy(this.styleModule); }}; protected var _styles_:Array = []; public function pushStyle(style:CSSStyleDeclaration):void { _styles_.push(style); } //============================================================ public function setStyleDeclarations(styleManager:IStyleManager2):void { // (trace)("StyleModule.setStyleDeclarations();", styleManager); if (!styleManager) { styleManager = StyleManagerCls["getStyleManager"](null); } this.styleManager = styleManager; // clone styles with new styleManager for (var i:int = 0; i < _styles_.length; ++i) { var oldStyle:CSSStyleDeclaration = _styles_[i] as CSSStyleDeclaration; var selector:CSSSelector = oldStyle.selector; var selectorString:String = selector.toString(); var newStyle:CSSStyleDeclaration = styleManager.getStyleDeclaration(selectorString); if (!newStyle) { newStyle = new CSSStyleDeclaration(selector, styleManager); selectors.push(selectorString); } // register override map and keys var factory:Function = oldStyle.factory; var dumpObj:Object = {}; factory.apply(dumpObj); var keys:Array = overrideMap[selectorString]; overrideMap[selectorString] ||= keys ||= []; for (var key:* in dumpObj) { newStyle.mx_internal::setLocalStyle(key, dumpObj[key]); keys.push(key); } // register effects map var addedEffects:Array; // (trace)("effects:", oldStyle.mx_internal::effects); newStyle.mx_internal::effects ||= oldStyle.mx_internal::effects ||= []; addedEffects = newStyle.mx_internal::effects.concat(); effectMap[selectorString] = addedEffects; } } //============================================================ // original external style module functions public function unload():void { // (trace)("StyleModule.unload();"); unloadOverrides(); unloadStyleDeclarations(); if (unloadGlobal) { styleManager.stylesRoot = null; styleManager.initProtoChainRoots(); } } private function unloadOverrides():void { // (trace)("StyleModule.unloadOverrides();"); for (var selector:String in overrideMap) { // (trace)("selector:", selector); var style:CSSStyleDeclaration = styleManager.getStyleDeclaration(selector); if (style != null) { var keys:Array = overrideMap[selector]; var numKeys:int; var i:uint; if (keys != null) { numKeys = keys.length; for (i = 0; i < numKeys; i++) { // (trace)("clearOverride:", keys[i]); style.mx_internal::clearOverride(keys[i]); } } keys = effectMap[selector]; if (keys != null) { numKeys = keys.length; var index:uint; var effects:Array = style.mx_internal::effects; for (i = 0; i < numKeys; i++) { // ReferenceError: Error #1069: Number 上找不到屬性 0,而且沒有預設值。 // index = effects.indexOf(numKeys[i]); index = effects.indexOf(keys[i]); if (index >= 0) { effects.splice(index, 1); } } } } } overrideMap = null; effectMap = null; } private function unloadStyleDeclarations():void { // (trace)("StyleModule.unloadStyleDeclarations();"); var numSelectors:int = selectors.length; for (var i:int = 0; i < numSelectors; i++) { var selector:String = selectors[i]; styleManager.clearStyleDeclaration(selector, false); } selectors = null; } //============================================================ } }
完成之後,就可以用一般 Flex Module 方式來開發外部 Style 了
<?xml version="1.0" encoding="utf-8"?> <module:StyleModule xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:module="com.ticore.style.module.*"> <fx:Style source="style/Style01.css"/> <fx:Style source="style/Style02.css"/> </module:StyleModule>
搞了這麼麻煩,這種自訂 Style Module 方式倒底有什麼好處呢?
以上的問題與技巧同時適用於 Flex 4, 4.5
RichMedia+ 来源于“更好的富媒体”的含义,博客也一同分享在富媒体应用开发中,特别是Flash, Flex这一块碰到的问题。
因此也希望能有共同兴趣和爱好的朋友在一起,分享工作当中所碰到的关于“更好的富媒体”的问题,无论是从Code出发还是从User Experience出发。
非常高兴 Ticore(台湾) , hack86(杭州) 一起成为 RichMedia+ 的维护者,一起维护这个Blog,分享他们在工作当中碰到的问题和经验。
因此 RichMedia+ 不再是一个人,是一群有相同兴趣爱好的团队,如果你也希望加入我们一起成长,请联系 aedisju[at]gmail.com
“专注在每件事的限制或弱点,是成不了大事的。你要专注每件事的可能性和潜在价值上。” 基辛格谈他从历届美国总统身上学到什么。
很多人都打算或正在创业,但面临着各种各样问题,寻寻觅觅寻不着靠谱的建议。Duck Duck Go 创始人、天使投资人 Gabriel Weinberg 用一张流程图来介绍创业的整个过程,简单明了,一目了然。好的话别忘了转给你的好友看看。

转载自@36氪