実行時のスタイルシートのロード

実行時にスタイルシートをロードするには、StyleManager を使用します。これらのスタイルシートは、Flex アプリケーションの実行中に動的にロードされる SWF ファイルの形式を取ります。

実行時にスタイルシートをロードすると、イメージ (グラフィカルスキン用)、フォント、タイプセレクタとクラスセレクタ、およびプログラムスキンを、コンパイル時に埋め込まずに Flex アプリケーションにロードできます。この方法では、スキンとフォントを、メインアプリケーションとは分離した別個の SWF ファイルに分割することができます。その結果、アプリケーションの SWF ファイルのサイズは縮小し、初期ダウンロードの時間は短縮されます。ただし、実行時スタイルシートを初めて使用するときは、必要な CSS ベースの SWF ファイルを Flex にダウンロードする必要があるため、スタイルおよびスキンの適用に時間がかかります。

実行時にスタイルシートをロードするには、次の 3 つの手順を実行します。

  1. アプリケーションの CSS ファイルを作成します。
  2. mxmlc コンパイラを使用して CSS ファイルを SWF ファイルにコンパイルします。
  3. Flex アプリケーションで StyleManager.loadStyleDeclarations() メソッドを呼び出します。このメソッドは、CSS ベースの SWF ファイルをアプリケーションにロードします。このメソッドが実行されると、新しい CSSStyleDeclarations が StyleManager にロードされます。

同一のスタイルを定義する複数のスタイルシートをロードできます。スタイルを設定すると、それ以降のスタイルシートが、共通のセレクタを持つ以前のスタイルシートを上書きすることがあります。ただし、実行時スタイルシートでロードされたスタイルが、コンパイル時のスタイルに完全に取って代わるわけではありません。実行時スタイルシートがアンロードされるまでオーバーライドするだけです。アンロードが実行されると、コンパイル時のスタイル設定に戻ります。コンパイル時のスタイル設定には、コンパイル時にロードされたデフォルトのスタイルシート、theme コンパイルオプションを使用してロードされたテーマファイル、MXML ファイル内で <mx:Style> ブロックを使用して設定されたスタイルなどが含まれます。

実行時スタイルシートの作成

実行時にスタイルシートをロードするには、最初に、SWF ファイルにコンパイルされたスタイルシートを作成する必要があります。実行時のスタイルシートは、他のスタイルシートと同様です。次の例に示すように、基本的なスタイルプロパティを設定するだけの簡単なスタイルシートにすることもできます。

/* styles/runtime/assets/BasicStyles.css */
Button {
    fontSize:    24;
    color: #FF9933;
}

Label {
    fontSize:    24;
    color: #FF9933;
}

あるいは、次の例に示すように、プログラムスキンやグラフィックスキン、フォントなどのスタイルプロパティが埋め込まれ、タイプセレクタやクラスセレクタを使用する複雑なスタイルシートにすることもできます。

/* styles/runtime/assets/ComplexStyles.css */
Application {
    backgroundImage : "assets/greenBackground.gif";
    theme-color: #9DBAEB;
}
Button {
    fontFamily: Tahoma;
    color: #000000;
    fontSize: 11;
    fontWeight: normal;
    text-roll-over-color: #000000; 
    upSkin: Embed(source="../../../assets/orb_up_skin.gif");
    overSkin: Embed(source="../../../assets/orb_over_skin.gif");
    downSkin: Embed(source="../../../assets/orb_down_skin.gif");
}

.noMargins {
    margin-right: 0;
    margin-left: 0;
    margin-top: 0;
    margin-bottom: 0;
    horizontal-gap: 0;
    vertical-gap: 0;
}

実行時に、コンパイルされていない CSS ファイルを Flex アプリケーションにロードすることはできません。CSS ファイルをロードする前に、必ず SWF ファイルにコンパイルしてください。

CSS ベースの SWF ファイルのコンパイル

実行時にスタイルシートをロードできるようにするには、事前にスタイルシートを SWF ファイルにコンパイルする必要があります。

CSS ファイルを SWF ファイルにコンパイルするには、mxmlc コマンドラインコンパイラを使用します。デフォルトでは、コンパイルの結果、CSS ファイルと同じ名前で拡張子が .swf の SWF ファイルが生成されます。次の例では、"BasicStyles.swf" ファイルが生成されます。

> mxmlc /skins/runtime/BasicStyles.css

SWF ファイルにコンパイルするスタイルシートには、.css のファイル名拡張子が付いている必要があります。

Flex アプリケーションをコンパイルするときに、コンパイルは、そのアプリケーションが使用する CSS ベースの SWF ファイルに対してコンパイル時のリンクチェックを実行しません。つまり、メインアプリケーションをコンパイルする前に SWF ファイルを作成する必要はありません。

実行時のスタイルシートのロード

実行時に CSS ベースの SWF ファイルをロードするには、StyleManager の loadStyleDeclarations() メソッドを使用します。このメソッドを使用するには、mx.core.StyleManager クラスを読み込む必要があります。

次の例では、ボタンをクリックしたときに、スタイルシートをロードします。

<?xml version="1.0"?>
<!-- styles/runtime/BasicApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
        import mx.styles.StyleManager;
        
        public function applyRuntimeStyleSheet():void {
            StyleManager.loadStyleDeclarations("assets/BasicStyles.swf")
        }
        ]]>
    </mx:Script>    
    
    <mx:Label text="Click the button to load a new CSS-based SWF file"/>
    <mx:Button id="b1" label="Click Me" click="applyRuntimeStyleSheet()"/>

</mx:Application>

loadStyleDeclarations() メソッドの第 1 パラメータは、ロードするスタイルシートの場所を示します。ローカルまたはリモートの場所を指定できます。

次の例は、ローカルの SWF ファイルとリモートの SWF ファイルのロードを示しています。

// Load a locally-accessible style sheet:
StyleManager.loadStyleDeclarations("assets/LocalStyles.swf");
// Load a remote style sheet:
StyleManager.loadStyleDeclarations("http://www.domain2.com/styles/RemoteStyles.swf", true, true);

スタイルシートがローカル (ロードするアプリケーションと同じドメインから見て) の場合は、追加の設定なしでスタイルシートをロードできます。スタイルシートの場所がリモートの場合 (つまり、ロードするアプリケーションのドメインと完全に一致するドメイン以外)、loadStyleDeclarations() メソッドの第 3 パラメータ trustContenttrue に設定する必要があります。リモートのスタイルシートをロードする場合、ロードするアプリケーションに SWF ファイルのロードを許可する "crossdomain.xml" ファイルは不要です。

また、リモートのスタイルシートを使用するには、ネットワークアクセスが可能なロードアプリケーション (use-network コンパイラプロパティがデフォルトの true に設定されている) をコンパイルする必要があります。アプリケーションをローカルファイルシステムでコンパイルして実行すると、リモートアクセスが可能な SWF ファイルをロードできなくなることがあります。

loadStyleDeclarations() メソッドは IEventDispatcher クラスのインスタンスを返します。このオブジェクトを使用すると、スタイルシートのロードが成功しだかどうかに応じてイベントをトリガできます。ロードプロセスの StyleEvent.PROGRESSStyleEvent.COMPLETEStyleEvent.ERROR の各イベントにアクセスできます。

次のアプリケーションは、スタイルシートのロードが終了したときにメソッドを呼び出します。

<?xml version="1.0"?>
<!-- styles/runtime/StylesEventApp.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">

    <mx:Script>
        <![CDATA[
        import mx.styles.StyleManager;
        import mx.events.StyleEvent;
        
        public function init():void {
            var myEvent:IEventDispatcher = 
                StyleManager.loadStyleDeclarations("assets/ACBStyles.swf");
            myEvent.addEventListener(StyleEvent.COMPLETE, getImage);
        }

        private function getImage(event:StyleEvent):void {
            map1.source = acb.getStyle("dottedMap");
        }        
        ]]>
    </mx:Script>    
    
    <mx:ApplicationControlBar id="acb" width="100%" styleName="homeMap">
        <mx:Image id="map1"/>
        <mx:Button label="Submit"/>
    </mx:ApplicationControlBar>
    
</mx:Application>

loadStyleDeclarations() メソッドの第 2 パラメータは、update です。update パラメータを true に設定すると、即時にスタイルが強制的に適用されます。アプリケーションのスタイルを強制的に即時更新しないようにするには、false に設定します。スタイルは、次回、このメソッドまたは、update プロパティが true 設定されている unloadStyleDeclarations() メソッドを呼び出したときに更新されます。

update パラメータが true 設定されている loadStyleDeclarations() メソッドを呼び出すたびに、Adobe Flash Player ではすべてのスタイルが表示リストに再適用され、これが原因でパフォーマンスが低下することがあります。同時に複数の CSS ベースの SWF ファイルをロードする場合は、最後の呼び出しを除くこのメソッドへのすべての呼び出しで、update パラメータを false に設定する必要があります。そのように設定すると、Flash Player では、新しいスタイル SWF ファイルごとに適用するのではなく、新しいすべての SWF ファイルに対して一度にスタイルを適用します。

次の例では、3 種類のスタイルの SWF ファイルをロードしますが、3 番目のファイルがロードされるまでスタイルは適用されません。

<?xml version="1.0"?>
<!-- styles/runtime/DelayUpdates.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">

    <mx:Script> 
        <![CDATA[
        import mx.styles.StyleManager;
        import mx.events.StyleEvent;
        
        public function init():void {
            StyleManager.loadStyleDeclarations(
                "assets/ButtonStyles.swf", false);
            var myEvent:IEventDispatcher = 
                StyleManager.loadStyleDeclarations(
                "assets/LabelStyles.swf", false);            
            myEvent.addEventListener(StyleEvent.COMPLETE, doUpdate);
        }

        public function doUpdate(event:StyleEvent):void {
            StyleManager.loadStyleDeclarations(
                "assets/ACBStyles.swf", true);
        }
        ]]>
    </mx:Script>    
    
    <mx:Label text="This is a label"/>

    <mx:ApplicationControlBar id="acb" width="100%">
        <mx:Button label="Submit"/>
    </mx:ApplicationControlBar>
    
</mx:Application>

実行時のスタイルシートのアンロード

実行時にロードしたスタイルシートをアンロードすることができます。そのためには、StyleManager の unloadStyleDeclarations() メソッドを使用します。このメソッドの結果、指定したスタイルの SWF ファイルで設定されたすべてのスタイルプロパティが、デフォルト値に戻されます。

次の例では、チェックボックスを切り替えたときに、スタイル SWF をロードまたはアンロードします。

<?xml version="1.0"?>
<!-- styles/runtime/UnloadStyleSheets.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script> 
        <![CDATA[
        import mx.styles.StyleManager;
        
        public function toggleStyleSheet():void {
            if (cb1.selected == true) {
                StyleManager.loadStyleDeclarations(
                    "assets/ButtonStyles.swf", true, false)
                StyleManager.loadStyleDeclarations(
                    "assets/LabelStyles.swf", true, false)
            } else {
                StyleManager.unloadStyleDeclarations(
                    "assets/ButtonStyles.swf", true);
                StyleManager.unloadStyleDeclarations(
                    "assets/LabelStyles.swf", true);
            }                       
        }
        ]]>
    </mx:Script>    

    <mx:Button id="b1" label="Click Me"/>
    
    <mx:Label id="l1" text="Click the button"/>
    
    <mx:CheckBox id="cb1" 
        label="Load style sheet" 
        click="toggleStyleSheet()" 
        selected="false"
    />
</mx:Application>

カスタムコンポーネントでの実行時スタイルシートの使用

実行時スタイルシートは、カスタムコンポーネントでも使用できます。そのためには、通常、コンポーネントが初期化された後に loadStyleDeclaration() メソッドを呼び出します。スタイルシートにクラスセレクタがある場合は、styleName プロパティを設定することにより適用します。

次の例では、specialStyle という名前のクラスセレクタにあるスタイルプロパティとスキンを定義します。

/* styles/runtime/assets/CustomComponentStyles.css */
.specialStyle {
    fontSize:    24;
    color: #FF9933;
    upSkin: Embed(source="SubmitButtonSkins.swf", symbol="MyUpSkin");
    overSkin: Embed(source="SubmitButtonSkins.swf", symbol="MyOverSkin");
    downSkin: Embed(source="SubmitButtonSkins.swf", symbol="MyDownSkin");
}

次の例では、カスタムコンポーネントがこのスタイルシートをロードし、初期化中に specialStyle クラスセレクタをそれ自体に適用します。

// styles/runtime/MyButton.as -->
package {

    import mx.controls.Button;
    import mx.events.*;
    import mx.styles.StyleManager;
    
    public class MyButton extends Button {
   
        public function MyButton() {
            addEventListener(FlexEvent.INITIALIZE, 
                initializeHandler);
        }

         // Gets called when the component has been initialized
        private function initializeHandler(event:FlexEvent):void {
            StyleManager.loadStyleDeclarations(
                "assets/CustomComponentStyles.swf");
            this.styleName = "specialStyle";
        }
    }    
}

実行時スタイルシートとしてのテーマ SWC ファイルの使用

既存のテーマ SWC ファイルがある場合は、そのファイルを実行時スタイルシートとして使用できます。そのためには、テーマ SWC ファイルから CSS ファイルを抽出する必要があります。その後に、残りの SWC ファイルを 1 つのライブラリとして渡すことにより、スタイル SWF ファイルをコンパイルします。

次の手順は、コマンドラインを使用してこのプロセスを実行する方法を示しています。

  1. PKZip などのアーカイブユーティリティを使用して、SWC ファイルから CSS ファイルを抽出します。
    $ unzip haloclassic.swc defaults.css
    
  2. (オプション) CSS ファイルの名前を、意味のある名前に変更します。この名前がスタイル SWF ファイルの名前になります。次の例では、ファイル名を "defaults.css" から "haloclassic.css" に変更します。
    $ mv defaults.css haloclassic.css
    
  3. スタイル SWF ファイルをコンパイルします。テーマ SWC ファイルをスタイル SWF ファイルに追加するには、次の例に示すように、include-libraries オプションを使用します。
    $ mxmlc -include-libraries=haloclassic.swc haloclassic.css
    

テーマ SWC ファイル内に複数の CSS ファイルがある場合は、スタイル SWF ファイルをコンパイルする前に CSS ファイルをすべて抽出する必要があります。


Flex 2.01