Adobe Flex 3 ヘルプ

ステートフルスキンの作成

ステートフルスキンは、Button、Slider、NumericStepper などの多くの Flex コンポーネントでサポートされています。ステートフルスキンは、ビューステートを使用して、コンポーネントの様々な状態に対するスキンを指定します。ビューステートの詳細については、ビューステートの使用を参照してください。

『Adobe Flex リファレンスガイド』の説明に従って、スキンプロパティでステートフルスキンをサポートするかどうかを指定できます。例えば、すべてのステートフルスキンプロパティには、次に示す形式で TitleWindow.closeButtonSkin プロパティの文が含まれています。

closeButtonSkin スタイルを使用して、disabled、down、over、up 状態のスキンを割り当てることができます。

ステートフルスキンとして機能するには、スキンは IStateClient インターフェイスを実装している必要があります。このインターフェイスは UIComponent によって実装されるので、UIComponent の任意のサブクラスを使用して、ステートフルスキンを定義できます。次に、ステートフルスキンクラスをコンポーネントのステートフルスキンプロパティに割り当てます。

例えば、Button コントロールには 8 つの状態と 8 つの関連付けられたスキンがあります。8 つのすべての状態に対するスキンを定義する単一のスキンクラスを作成するには、UIComponent コンポーネントに基づくスキンを作成します。その後、各ビューステートの名前が Button コントロールの状態に対応するスキン内に 8 つのビューステートを定義します。次に例を示します。

<?xml version="1.0"?>
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:states>
        <mx:State name="down">
        </mx:State>
 
        <mx:State name="over">
        </mx:State>
        
        ...

        <mx:State name="selectedUp">
        </mx:State>
    </mx:states>

    <mx:Script>
        <![CDATA[ 
            <!-- Define the skin by using the Flash drawing API. -->
        ]]>
    </mx:Script>
</mx:UIComponent>

注意: ActionScript または MXML のいずれかで、ステートフルスキンを作成できます。このセクションの例では、少ないコード行でビューステートを定義できるので MXML を使用します。

ステートフルスキンを定義したら、そのスキンをコントロールの skin スタイルプロパティに割り当てます。CSS、setStyle() メソッド、インラインスタイル または StyleManager クラスを使用して、ステートフルスキンを割り当てることができます。次に CSS を使用してステートフルスキンを設定する例を示します。

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

    <mx:Style>
        Button {
            skin: ClassReference("myComponents.MyButtonStatefulSkinAll");
        } 
    </mx:Style>  

    <mx:Button label="Hello" id="b" />
</mx:Application> 

前の例で実行する SWF ファイルは以下のとおりです。

詳細については、スキンの適用を参照してください。

8 つのすべてのスキンを定義する必要はありません。作成したいスキンのみ定義します。その他すべてのスキンについては、Flex に付属のデフォルトスキンを使用します。次のステートフルスキンコンポーネントでは、Button コントロールの up 状態と over 状態のスキンのみ定義します。

<?xml version="1.0"?>
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:states>
        <mx:State name="up">
        </mx:State> 

        <mx:State name="over">
        </mx:State> 
    </mx:states>
... 
</mx:UIComponent>

その後、このコンポーネントをスキンスタイルプロパティの値として指定するか、残りの 6 つのプロパティのデフォルトスキンを指定します。次に例を示します。

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

    <mx:Style>
        Button {
          skin: ClassReference("ButtonUpStatefulSkin");
          downSkin: ClassReference("mx.skins.halo.ButtonSkin");
          disabledSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedUpSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedOverSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedDownSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedDisabledSkin: ClassReference("mx.skins.halo.ButtonSkin");
        }
  </mx:Style>

    <mx:Button id="b1" label="Click Me"/>
</mx:Application>

前の例で実行する SWF ファイルは以下のとおりです。

例:ステートフルスキンの作成

ステートフルスキンはプログラムスキンなので、プログラムスキンのレシピで定義されたルールを使用して定義する必要があります。つまり、updateDisplayList() メソッドのオーバーライドを定義する必要があります。また、ActionScript クラスでは、コンストラクタも定義します。

ビューステートを作成するには、基本ビューステートを定義してから、この基本ビューステートを変更する一連の変更またはオーバーライドを定義して、個々の新しいビューステートを定義します。新しいビューステートでは、子コンポーネントの追加または削除、スタイル値やプロパティの値の設定、状態固有のイベントリスナーの定義などによって、基本ビューステートを変更できます。

ステートフルスキンを定義する最も一般的な方法の 1 つは、ビューステートごとに変更できる複数のプロパティまたはスタイルを持つスキンを定義する方法です。例えば、次のステートフルスキンでは、Button コントロールで使用するスキンの線の太さ、塗りの色、およびドロップシャドウを制御するプロパティを定義します。

<?xml version="1.0"?>
<!-- skins/myComponents/MyButtonStatefulSkin.mxml -->
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml">

  <mx:Script>
    <![CDATA[      
      import flash.filters.DropShadowFilter;
            
      // Define a drop shadow for the over and down states.
      [Bindable]
      private var myFilter:DropShadowFilter = new DropShadowFilter(0);
                 
      // Define a private var for line weight.
      private var _lineWeight:Number = 1;
            
      // Define public setter and getter for line weight.
      public function get lineWeight():Number
      {
        return _lineWeight;
      }
            
      public function set lineWeight(value:Number):void
      {
        _lineWeight = value;
        invalidateDisplayList();
      }
            
      // Define a private var for the fill color.
      private var _rectFill:uint = 0x00FF00;
            
      // Define public setter and getter for fill color.
      public function get rectFill():uint
      {
        return _rectFill;
      }
            
      public function set rectFill(value:uint):void
      {
        _rectFill = value;
        invalidateDisplayList();
      }

      override protected function updateDisplayList(unscaledWidth:Number, 
          unscaledHeight:Number):void
      {
        graphics.lineStyle(lineWeight, 0x0066FF);
        graphics.beginFill(rectFill, 0.50);
        graphics.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 10, 10);
        filters = [myFilter];
      }                      
    ]]>
  </mx:Script>
    
    <mx:states>
        <mx:State name="up">
        </mx:State>
        <mx:State name="over">
            <mx:SetProperty target="{this}" 
                name="rectFill" value="0x00CC33"/>
            <mx:SetProperty target="{myFilter}" 
                name="distance" value="4"/>
        </mx:State>
        <mx:State name="down">
            <mx:SetProperty target="{this}" 
                name="rectFill" value="0x00CC33"/>
            <mx:SetProperty target="{myFilter}" 
                name="inner" value="true"/>
            <mx:SetProperty target="{myFilter}" 
                name="distance" value="2"/>
        </mx:State>
    </mx:states>    
</mx:UIComponent>

この例では、次の状態のスキンを定義します。

up 

変更を一切定義しないでください。この結果、基本ビューステートが up 状態のスキンを定義します。



over 

塗りの色を 0x00CC33 に変更し、線の太さを 2 ピクセルに設定し、2 ピクセル幅のドロップシャドウを作成します。



down 

塗りの色を 0x00CC33 に変更し、ドロップシャドウのタイプを内側に設定し、2 ピクセル幅のドロップシャドウを作成します。



次のアプリケーションでは、このスキンを使用しています。

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

    <mx:Style>
        Button {
          skin: ClassReference("myComponents.MyButtonStatefulSkin");
          disabledSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedUpSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedOverSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedDownSkin: ClassReference("mx.skins.halo.ButtonSkin");
          selectedDisabledSkin: ClassReference("mx.skins.halo.ButtonSkin");
        } 
    </mx:Style>  

    <mx:Button label="Hello" id="b" />
</mx:Application> 

前の例で実行する SWF ファイルは以下のとおりです。

イメージを使用するステートフルスキンの作成

状態を変更するとスキンが異なるイメージを表示するステートフルスキンでイメージを使用できます。イメージを使用する場合の課題の 1 つは、最初にスキンを作成するときに、measuredWidth および measuredHeight プロパティの値を設定するか、そうでない場合はスキンの高さと幅が 0 に設定されるようにして、基本ビューステートにイメージを組み込む必要があることです。

次の例では、Button コントロールの up、over、down および disabled 状態のイメージを埋め込みます。

<?xml version="1.0" encoding="utf-8"?>
<!-- skins/myComponents/MyButtonStatefulSkinImages.mxml -->
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">

    <mx:Script>
        <![CDATA[
            // Embed the skin images.
            [Bindable]
            [Embed(source="../../assets/orb_up_skin.gif")]
            private var buttonUp:Class;

            [Bindable]
            [Embed(source="../../assets/orb_over_skin.gif")]
            private var buttonOver:Class;

            [Bindable]
            [Embed(source="../../assets/orb_down_skin.gif")]
            private var buttonDown:Class;

            [Bindable]
            [Embed(source="../../assets/orb_disabled_skin.gif")]
            private var buttonDisabled:Class;
        ]]>
    </mx:Script>

    <mx:states>
        <mx:State name="up"/>
        <mx:State name="notBase">
            <mx:RemoveChild target="{baseButton}"/>
        </mx:State>
        <mx:State name="over" basedOn="notBase">
            <mx:AddChild creationPolicy="all">
                <mx:Image source="{buttonOver}" 
                    maintainAspectRatio="false" 
                    width="100%" height="100%"/> 
            </mx:AddChild>
        </mx:State>
        <mx:State name="down" basedOn="notBase">
            <mx:AddChild creationPolicy="all">
                <mx:Image source="{buttonDown}" 
                    maintainAspectRatio="false" 
                    width="100%" height="100%"/> 
            </mx:AddChild>
        </mx:State>
        <mx:State name="disabled" basedOn="notBase">
            <mx:AddChild creationPolicy="all">
                <mx:Image source="{buttonDisabled}" 
                    maintainAspectRatio="false" 
                    width="100%" height="100%"/> 
            </mx:AddChild>
        </mx:State>
    </mx:states>
    
    <mx:Image id="baseButton" 
        width="100%" height="100%"
        source="{buttonUp}" 
        maintainAspectRatio="false"/>    
</mx:Canvas>

この例では、スキンは次のアクションを実行します。

  • 基本ビューステートの変更を定義せずに up ビューステートを作成します。
  • notBase ビューステートを定義して、基本ビューステートによって定義されたイメージを削除します。up ビューステートを除く、その他すべてのビューステートは notBase ビューステートに基づきます。
  • 各 AddChild タグに対して、creationPolicy プロパティを all に設定します。このプロパティは、最初のビューステートの変更時ではなく、アプリケーションの起動時に子インスタンスを作成するように指定します。この結果、最初にビューステートを表示する際のちらつきを防止します。詳細については、ビューステートの使用を参照してください。
  • Canvas コンテナが個々の Image コントロールではなく、スキンの親によってサイズが変更されるものなので、イメージタグの width および height プロパティを 100 %に設定します。この設定により、スキンのサイズが親のサイズになるように Image コントロールが構成されます。
  • イメージが Canvas コンテナのフルサイズ全体に伸長するように、各イメージタグの maintainAspectRatio プロパティを false に設定します。

ステートフルスキンでのトランジションの使用

ビューステートを使用すると、通常はユーザーの操作に対する応答として、コンポーネントの外観を変更できます。トランジションは、ビューステートの変化が画面上でどのように表示されるかを定義します。トランジションは、エフェクトクラスを使用して定義します。このとき、トランジションを処理するために明示的に設計された複数のエフェクトを組み合わせます。トランジションの詳細については、トランジションの使用を参照してください。

次の例では、前のセクションのステートフルスキンの定義にトランジションを追加します。この例では、トランジションは、スキンの塗りの色を変更する際に表示される 100 ミリ秒のアニメーションを定義します。

<?xml version="1.0"?>
<!-- skins/myComponents/MyButtonStatefulSkinTrans.mxml -->
<mx:UIComponent xmlns:mx="http://www.adobe.com/2006/mxml">

  <mx:Script>
    <![CDATA[      
      import flash.filters.DropShadowFilter;
            
      // Define a drop shadow for the over and down states.
      [Bindable]
      private var myFilter:DropShadowFilter = new DropShadowFilter(0);
                 
      // Define a private var for line weight.
      private var _lineWeight:Number = 1;
            
      // Define public setter and getter for line weight.
      public function get lineWeight():Number
      {
        return _lineWeight;
      }
            
      public function set lineWeight(value:Number):void
      {
        _lineWeight = value;
        invalidateDisplayList();
      }
            
      // Define a private var for the fill color.
      private var _rectFill:uint = 0x00FF00;
            
      // Define public setter and getter for fill color.
      public function get rectFill():uint
      {
        return _rectFill;
      }
            
      public function set rectFill(value:uint):void
      {
        _rectFill = value;
        invalidateDisplayList();
      }

      override protected function updateDisplayList(unscaledWidth:Number, 
          unscaledHeight:Number):void
      {
        graphics.lineStyle(lineWeight, 0x0066FF);
        graphics.beginFill(rectFill, 0.50);
        graphics.drawRoundRect(0, 0, unscaledWidth, unscaledHeight, 10, 10);
        filters = [myFilter];
      }                      
    ]]>
  </mx:Script>
        
    <mx:states>
        <mx:State name="up">
        </mx:State>
        <mx:State name="over">
            <mx:SetProperty target="{this}" 
                name="rectFill" value="0x00CC33"/>
            <mx:SetProperty target="{myFilter}" 
                name="distance" value="4"/>
        </mx:State>
        <mx:State name="down">
            <mx:SetProperty target="{this}" 
                name="rectFill" value="0x00CC33"/>
            <mx:SetProperty target="{myFilter}" 
                name="inner" value="true"/>
            <mx:SetProperty target="{myFilter}" 
                name="distance" value="2"/>
        </mx:State>
    </mx:states>    

    <mx:transitions>
        <mx:Transition>
            <mx:AnimateProperty target="{this}" 
                property="rectFill" duration="100"/>
        </mx:Transition>
    </mx:transitions>        
</mx:UIComponent>

 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート