Adobe Flex 3 ヘルプ

プログラムスキンの作成

プログラムスキンを ActionScript クラスまたは MXML コンポーネントとして作成し、Flash Graphics(flash.display.Graphics)パッケージの基本描画メソッドを使用して、これらのスキンを Flex コントロールに適用します。

Flex に付属のプログラムスキンを修正して使用できるほか、独自のスキンを作成することもできます。Flex コンポーネントで使用するプログラムスキンは、mx.skins.halo パッケージに収められています。これらのすべてのスキンは、UIComponentProgrammaticSkinBorderRectangularBorder のいずれかのクラスを拡張します。

独自のスキンの作成に関する詳細については、プログラムスキンのレシピを参照してください。

ステートフルスキンと呼ばれるプログラムスキンの 1 つのタイプは、ビューステートを使用します。ステートフルスキンの作成に関する詳細については、ステートフルスキンの作成を参照してください。

ActionScript および MXML スキンの作成

プログラムスキンを ActionScript クラスまたは MXML コンポーネントとして作成します。MXML コンポーネントを使用すると、Flex では多くのクラス定義のオーバーヘッドが処理されるので、スキンを MXML コンポーネントとして定義するほうが簡単な場合があります。MXML コンポーネントの唯一の制約は、コンストラクタを定義できないことです。代わりに、preinitialize イベントのイベントハンドラを使用して、ActionScript コンストラクタで行う操作を実行します。

ActionScript クラスと MXML コンポーネントの作成に関する詳細については、『Adobe Flex 3 コンポーネントの作成と拡張』を参照してください。

プログラムスキンのレシピ

プログラムスキンは、少なくとも、ActionScript クラス用のコンストラクタ、updateDisplayList() メソッド、およびスキンプロパティ用の getter と setter で構成されています。通常、プログラムスキンは、mx.skins パッケージまたは UIComponent クラスのいずれかのクラスを拡張します。

プログラムスキンのレシピに従ったスキンの例を見るには、mx.skins.halo パッケージの具象クラスを参照してください。このクラスには、Flex コンポーネントで使用されるスキンが収められています。これらのスキンは、ここで紹介するものと同じレシピに従っています。

次の例は、プログラムスキンの代表的なアウトラインを示しています。

package { // Use unnamed package if this skin is not in its own package.
  // skins/MySkinOutline.as
  
  // Import necessary classes here.
  import flash.display.Graphics;
  import mx.skins.Border;
  import mx.skins.ProgrammaticSkin;
  import mx.styles.StyleManager;

  // Extend ProgrammaticSkin.
  public class MySkinOutline extends ProgrammaticSkin {

     // Constructor.
     public function MySkinOutline() {
        // Set default values here.
     }

     // Override updateDisplayList().
     override protected function updateDisplayList(w:Number, 
        h:Number):void {
        // Add styleable properties here.
        // Add logic to detect components state and set properties here.
        // Add drawing methods here.
     }
  }
} // Close unnamed package.

Flex アプリケーションでは、CSS で ClassReference ステートメントを使用して、プログラムスキンを適用できます。

<?xml version="1.0"?>
<!-- skins/ApplyMySkinOutline.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Style>
     Button {
        overSkin: ClassReference("MySkinOutline");
        upSkin: ClassReference("MySkinOutline");
        downSkin: ClassReference("MySkinOutline");
     }
  </mx:Style>
  <mx:Button id="b1" label="Click Me"/>
</mx:Application>

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

スキンのインターフェイスまたは基本クラスの選択

スキンのクラスは、1 つまたは複数のインターフェイスを実装する必要があります。プログラムスキンを作成する場合は、必要なインターフェイスを実装するクラスを作成するか、必要なインターフェイスが既に実装されているクラスのサブクラスを作成することができます。

作成するスキンのタイプによって、どのインターフェイスを実装するか、またはスキンの基本クラスとしてどのクラスを使用するかの決定が異なる場合があります。例えば、境界線を定義するスキンを作成する場合は、Border クラスのサブクラスを作成できます。ステートフルスキンを作成する場合は、UIComponent コンポーネントのサブクラスを作成するか、IStateClient インターフェイスを実装するクラスを作成することができます。

mx.skins パッケージの抽象基本クラスまたは mx.skins.halo パッケージの具象クラスを拡張できます。mx.skins パッケージの抽象基本クラスを拡張すると、スキンの外観と操作性を広範囲に制御できます。Flex コンポーネントのデフォルト動作を使用した上で、スタイルをいくつか追加する場合は、mx.skins.halo パッケージの具象クラスを拡張する方法が適しています。

考慮すべきいくつかのルールを次に示します。

  • ステートフルスキンは、IStateClient インターフェイスまたは IProgrammaticSkin インターフェイスのいずれかを実装する必要があります。UIComponent クラスが、IStateClient インターフェイスを実装します。ProgrammaticSkin クラスは、IProgrammaticSkin インターフェイスを実装します。
  • Button.upSkin または NumericStepper.upArrowOverSkin など、ステートフルスキンプロパティ以外のスキンプロパティに渡すスキンは、IFlexDisplayObject インターフェイスを実装している必要があります。UIComponent クラスおよび ProgrammaticSkin クラスは、IFlexDisplayObject インターフェイスを実装します。

ほとんどのスキンは mx.skins.ProgrammaticSkin クラスを拡張したものですが、次に示す任意のクラスと、スキン用のスーパークラスとして選択することができます。

  • ProgrammaticSkin クラスは、IFlexDisplayObjectILayoutManagerClientIInvalidatingISimpleStyleClient の各インターフェイスを実装しているので、最も扱いやすく、広く使用されるスーパークラスです。
  • Border クラスは、ProgrammaticSkin クラスを拡張して borderMetrics プロパティのサポートを追加したものです。スキンでコンポーネントの境界線を定義する場合は、このクラスまたは RectangularBorder クラスを使用します。
  • RectangularBorder クラスは、Border クラスを拡張して backgroundImage スタイルに対するサポートを追加したものです。
  • UIComponent クラスは IStateClient インターフェイスを実装しているので、ステートフルスキンの扱いが簡単です。また、このクラスは MXML でスキンを実装するときに使用するコンポーネントです。

Flex コントロール用のプログラムスキンを作成するには、次の手順に従います。各手順については、以下のセクションで詳しく説明します。

Flex コントロール用のプログラムスキンの作成

  1. 次の基本クラスのいずれかを、目的のプログラムスキンのスーパークラスとして選択します。

    mx.skins.Halo パッケージにある具象クラスのいずれかを拡張することもできます。詳細については、スキンのインターフェイスまたは基本クラスの選択を参照してください。

  2. updateDisplayList() メソッドを実装します。このメソッドに、すべての描画やスタイル変更の呼び出しを入れます。

    詳細については、updateDisplayList() メソッドの実装を参照してください。

  3. ActionScript クラスで、コンストラクタを実装します。
  4. (オプション)measuredWidth プロパティおよび measuredHeight プロパティの getter を実装します。

    詳細については、measuredWidth および measuredHeight の getter の実装を参照してください。

  5. スキンが Border または RectangularBorder のサブクラスである場合は borderMetrics プロパティの getter を実装します。

    詳細については、borderMetrics プロパティの getter の実装を参照してください。

  6. (オプション)プロパティをスタイル対応にします。

    作成したスキンのプロパティを、ユーザーが CSS または setStyle() メソッドへの呼び出しを使用して設定できるようにするには、スキンクラスにコードを追加する必要があります。詳細については、スタイル対応プロパティの作成を参照してください。

プログラムスキンのコンパイル

プログラムスキンを使用するアプリケーションをコンパイルする場合は、ActionScript クラスまたは MXML コンポーネントを扱うようにプログラムスキンを扱います。つまり、コンパイラの source-path 引数にスキンを追加する必要があります。コンパイルする MXML ファイルと同じディレクトリにスキンが存在する場合は、source-path をピリオドに設定します。次の例では、そのことを mxmlc コマンドラインコンパイラで示しています。

$ ./mxmlc -source-path=. c:/flex/MyApp.mxml

プログラムスキンがパッケージに含まれていない場合は、それらのスキンを外部から認識できるようにするため、名前のないパッケージに追加する必要があります。そのようにしないと、mxmlc はコンパイラエラーをスローします。スキンを追加するには、次の例のようにクラスを package ステートメントで囲みます。

package { // Open unnamed package.
    import flash.display.*;
    import mx.skins.ProgrammaticSkin;
    
    public class MySkin extends ProgrammaticSkin {
        ...
    }
} // Close unnamed package.

updateDisplayList() メソッドの実装

updateDisplayList() メソッドは、スキンの外観を定義します。このメソッドは、スキンの構築後に呼び出され、最初にスキンを描画します。それ以降は、コンポーネントのサイズ変更、スタイル変更、移動、または何らかの方法でやり取りが発生するたびに呼び出されます。

Flash Player の描画メソッドを使用して、updateDisplayList() メソッドでプログラムスキンを描画します。この描画メソッドの詳細については、プログラムによる描画を参照してください。

updateDisplayList() メソッドを実装する場合は、次の操作を行います。

  • override キーワードを使用して、スーパークラスの実装をオーバーライドします。
  • 戻り値の型を void に設定します。
  • このメソッドを protected として宣言します。

updateDisplayList() メソッドは、コンポーネントの高さと幅を引数として受け取ります。これらの引数の値を、描画可能な領域の境界線として使用します。このメソッドは void を返します。

スキンをレンダリングするには、Graphics クラスのメソッド(lineTo()drawRect() など)を使用します。コンポーネントのシェイプを追加する前に領域をクリアするには、描画を実行する前に clear() メソッドを呼び出します。このメソッドを実行すると、それまでの updateDisplayList() メソッドの呼び出しで得られた結果が消去され、その時点までに描画メソッドを使用して作成したイメージがすべて削除されます。lineStyle() メソッドで指定された線スタイルもすべてリセットされます。

Graphics パッケージのメソッドを使用するには、flash.display.Graphics クラスのほか、GradientType や Font など、flash.display パッケージ内の使用するクラスをすべて読み込む必要があります。次の例では、flash.display パッケージのすべてのクラスを読み込みます。

import flash.display.*;

次の例では、drawRect() メソッドを使用し、コンポーネントの周囲に境界として長方形を描画します。

g.drawRect(0, 0, width, height);

次の例では、X とその周囲に境界線を描きます。

package { // Use unnamed package if this skin is not in its own package.
  // skins/CheckboxSkin.as
  
  // Import necessary classes here.
  import flash.display.Graphics;
  import mx.skins.Border;
  import mx.skins.ProgrammaticSkin;
  import mx.styles.StyleManager;

  public class CheckboxSkin extends ProgrammaticSkin {

     // Constructor.
     public function CheckboxSkin() {
        // Set default values here.
     }

  override protected function updateDisplayList(w:Number, h:Number):void {
     var g:Graphics = graphics;
     g.clear();
     g.beginFill(0xFFFFFF,1.0);
     g.lineStyle(2, 0xFF0000);
     g.drawRect(0, 0, w, h);
     g.endFill();
     g.moveTo(0, 0);
     g.lineTo(w, h);
     g.moveTo(0, h);
     g.lineTo(w, 0);
  }
  }
} // Close unnamed package.

Graphics パッケージの一般的なメソッドの説明については、プログラムによる描画を参照してください。これらのメソッドの詳細については、『Adobe Flex リファレンスガイド』を参照してください。

updateDisplayList() メソッドで実行する一般的なタスクとして、コントロールの現在の状態に応じてスキンのプロパティを変更する処理があります。例えば、Button コントロール用のプログラムスキンを定義した場合、ユーザーが Button コントロールにマウスを移動するかクリックしたときに、その境界線の太さや背景色を変更することができます。

この状態を確認するには、スキンの name プロパティを使用します。name は、スキンの現在の名前を示しています。例えば、Button コントロール用のプログラムスキンを定義する場合、name プロパティはスキン状態を示す任意の値、つまり downSkinupSkinoverSkindisabledSkinselectedDisabledSkinselectedDownSkinselectedOverSkinselectedUpSkin のいずれかになります。

次の例では、Button コントロールの現在の状態をチェックし、さらに線の太さと背景の塗りの色を適切に調整します。具体的には、この Button コントロールをクリックすると、線の太さが 2 ポイントになるようにスキンが再描画されます。クリックしたマウスボタンを離すと、スキンがもう一度再描画され、線の太さがデフォルト値(4 ポイント)に戻ります。また、背景の塗りの色も、Button コントロールの状態に応じて変わります。

package { // Use unnamed package if this skin is not in its own package.
  // skins/ButtonStatesSkin.as

  // Import necessary classes here.
  import flash.display.Graphics;
  import mx.skins.Border;
  import mx.skins.ProgrammaticSkin;
  import mx.styles.StyleManager;

  public class ButtonStatesSkin extends ProgrammaticSkin {

     public var backgroundFillColor:Number;
     public var lineThickness:Number;

     // Constructor.
     public function ButtonStatesSkin() {
        // Set default values.
        backgroundFillColor = 0xFFFFFF;
        lineThickness = 4;
     }

     override protected function updateDisplayList(w:Number, h:Number):void {
        // Depending on the skin's current name, set values for this skin.
        switch (name) {
           case "upSkin":
            lineThickness = 4;
            backgroundFillColor = 0xFFFFFF;
            break;
           case "overSkin":
            lineThickness = 4;
            backgroundFillColor = 0xCCCCCC;
            break;
           case "downSkin":
            lineThickness = 2;
            backgroundFillColor = 0xFFFFFF;
            break;
           case "disabledSkin":
            lineThickness = 2;
            backgroundFillColor = 0xCCCCCC;
            break;
        }

        // Draw the box using the new values.
        var g:Graphics = graphics;
        g.clear();
        g.beginFill(backgroundFillColor,1.0);
        g.lineStyle(lineThickness, 0xFF0000);
        g.drawRect(0, 0, w, h);
        g.endFill();
        g.moveTo(0, 0);
        g.lineTo(w, h);
        g.moveTo(0, h);
        g.lineTo(w, 0);
     }
  }
} // Close unnamed package.

単一のプログラムスキンクラスを使用してコントロールの複数の状態を定義する場合、次の例に示すように、Flex アプリケーションでコントロールの適切な状態すべてにその単一のスキンを適用する必要があります。

<?xml version="1.0"?>
<!-- skins/ApplyButtonStatesSkin.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Style>
     Button {
        overSkin: ClassReference("ButtonStatesSkin");
        upSkin: ClassReference("ButtonStatesSkin");
        downSkin: ClassReference("ButtonStatesSkin");
     }
  </mx:Style>
  <mx:Button id="b1" label="Click Me"/>
</mx:Application>

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

スキンが RectangularBorder のサブクラスの場合は、updateDisplayList() メソッドの本体から super.updateDisplayList() も呼び出す必要があります。

 

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