Flex4でアイコン付きのカスタムボタンを作る

みなさん、Flex4(spark)は使ってますか?
今回の記事では、よく使うアイコン付きButtonコンポーネントをFlex4で作ってみたいと思います。

Flex3ではiconプロパティに、画像パスをセットしてあげればアイコンが表示できましたが、
Flex4のButtonにはiconプロパティがありませんので、カスタムButtonSkinを作成して、アイコンを実装します。

完成図はこんな感じです。表示するLabelも複数行にしました。

■ButtonSkinクラスの構成
カスタムButtonSkinの作成は、新規MXMLスキンでホストコンポーネントを(spark)Buttonにセットして生成できます。
すると、デフォルトのButtonSkinクラスがコピーされるので、ここにiconを表示するパーツを追加します。
MXMLで編集できるので、デザインビューで確認しながらスキンをカスタマイズできます。
追加する前に、デフォルトのButtonSkinの構成をまとめてみます。

1:ホストコンポーネント

<!– host component –>
<fx:Metadata>
<![CDATA[
   /**
   * @copy spark.skins.spark.ApplicationSkin#hostComponent
   */
   [HostComponent(“spark.components.Button”)]
]]>
</fx:Metadata>

このホストコンポーネントに当該Skinを使用するコンポーネントを指定することで、
そのコンポーネントのデータが取得できます。(例:親の幅を知る hostComponent.width)

2:ステート

<!– states –>
<s:states>
   <s:State name=”up” />
   <s:State name=”over” />
   <s:State name=”down” />
   <s:State name=”disabled” />
</s:states>

用意されたステートはこの4種です。これらステートによって、見た目を変える設定をするのは、
以下の「各レイヤー」で行います。

3: 各レイヤー

デフォルトでは、レイヤーは8つ用意されており、最上位にLabelが置いてあります。
以下の図は、レイヤー一枚ずつ重ねていった図になります。

layer2:fillのMXMLを見てみると、colorプロパティが複数ありますが、
color.over のように書いて、ステート毎にcolorが設定しています。

<s:Rect id=”fill” left=”1″ right=”1″ top=”1″ bottom=”1″ radiusX=”2″>
   <s:fill>
      <s:LinearGradient rotation=”90″>
         <s:GradientEntry color=”0xFF0000″
                  color.over=”0xBBBDBD”
                   color.down=”0xAAAAAA”
                  alpha=”0.85″ />
         <s:GradientEntry color=”0xD8D8D8″
                  color.over=”0x9FA0A1″
                  color.down=”0x929496″
                  alpha=”0.85″ />
      </s:LinearGradient>
   </s:fill>
</s:Rect>

■アイコンの追加

下記のようにLabelと、アイコン画像を埋め込んだBitmapImageコンポーネント並べます。
また、SparkのLabelは複数行が可能になったので、maxDisplayedLinesで行数が指定できます。

<s:HGroup left=”2″ right=”2″ top=”2″ bottom=”2″ verticalAlign=”contentJustify” gap=”1″>
   <!– icon –>
   <s:BitmapImage source=”@Embed(‘addIcon.png’)”/>
   
   <!– layer 8: text –>
   <!— @copy spark.components.supportClasses.ButtonBase#labelDisplay –>
   <s:Label id=”labelDisplay” text=”label”
         textAlign=”left” width=”100%”
         verticalAlign=”middle”
         maxDisplayedLines=”2″ >
   </s:Label>
</s:HGroup>

■スキンをあてる

出来たカスタムButtonSkinを、以下のようにButtonにあてます。

<s:Button skinClass=”CustomIconBtnSkin” width=”100″
         label=”長ーーーーーーーーーーーーーーいlabel” >
</s:Button>

■完成!…しましたが

これでButtonにアイコンが追加されましたが、複数のButtonにこのスキンをあてた場合、同じ固定画像がiconとして表示されます。
そこで、Flex3のようにButtonのiconプロパティに画像パスをセットして、Button毎に画像が変わるようにしたいと思います。

■カスタムButtonを作成する

Buttonを継承したCustomIconBtn.asを作成し、iconという名のstyleをメタタグで追加します

package
{
   import spark.components.Button;
   
   public class CustomIconBtn extends Button
   {
      //icons
      [Style(name=”icon”,type=”*”)]
      
      public function CustomIconBtn()
      {
         super();
      }
   }
}

■カスタムButtonSkinのiconを変更

<!–icon–>
<s:BitmapImage id=”icon”
             source=”{hostComponent.getStyle(‘icon’)}”/>

これで、ホストコンポーネントのiconの値を取得できます。

■完成!

<local:CustomIconBtn skinClass=”CustomIconBtnSkin” width=”100″
                  label=”長ーーーーーーーーーーーーーーいlabel”
                  icon=”@Embed(‘addIcon.png’)”>
</local:CustomIconBtn>

■感想

アイコンを表示するだけでファイルが増えてしまいましたが、Skinの編集で細かなところまでカスタマイズできます。
また、MXMLで編集できるので、デザインビューで確認しながらできるのも良いかと思います。
Flex3ならプロパティ設定で簡単に見た目を変更できたのに、Flex4(spark)で出来なくなったりして戸惑いもありますが、
コンポーネントのカスタマイズの敷居は大きく下がったように感じました。

Related Post

Flex Hero のモバイルアプリ開発でハマった点Flex Hero のモバイルアプリ開発でハマった点

「Flex Hero のモバイルアプリ開発の基本」では、ホントの基本のみのご紹介でした。今回は、実際に使ってみてハマった点をいくつかご紹介したいと思います。*なお、この記事は公開されているFlash Builder Buritto Preview版 を対象としています。 画面回転時のレイアウト

すぐに使えるFlexコネタ集すぐに使えるFlexコネタ集

昨日のおしゃれFxug勉強会にお越しいただいたみなさま、ありがとうございました。勉強会での発表より、ドリームページで使ったFlexコネタ集を。 1.scaleプロパティの活用 なんの変哲もないよく見かけるscaleプロパティを使った小技。Scaleを少し変更するだけで、同じインスタンスも素敵に変身します。 【Window領域に合わせた拡大表示】大きなディスプレイを使っている人は、Windowもめいいっぱい広げて使いたいもの。Flexでは表示サイズに合わせた%指定やパディングの指定もできすが、座標計算をして表示しているコンポーネントの場合、Windowサイズが変更されるときにいちいち計算をしなおすのは面倒。そんなときは、今のWindowサイズにおける表示可能領域とそのコンポーネントのサイズを比較して、何%拡大可能か計算します。それをscaleにセットするだけで、簡単にリキッド・レイアウトが実現できます。 【一覧表示】一覧表示や、Mini Map表示ならスケールダウン。scaleを小さく設定するだけでミニチュアコンポーネントが作れます。ミニチュアながらも機能はそのまま!なのがかわいらしい。必要に応じてステータスを変更しいらない機能は無効化しましょう。 scaleを変更するだけでいいので簡単です。インスタンスを使いまわせば経済的ですし、下手な計算なロジックを書いてバグを埋め込む心配もなし! 2.ドラッグプロキシーの活用