flex 4.5 simple spark button skinning

12,773

Solution 1

Here's a basic image button that's more general:

ImageButtonSkin.mxml

<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
             xmlns:s="library://ns.adobe.com/flex/spark" 
             xmlns:fb="http://ns.adobe.com/flashbuilder/2009">
    <fx:Metadata>
        [HostComponent("com.instantdelay.flex.commons.ImageSkinnableButton")]
    </fx:Metadata>
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
    <s:BitmapImage id="image"
                   source.up="{getStyle('upImage')}"
                   source.down="{getStyle('downImage')}"
                   source.over="{getStyle('overImage')}"
                   source.disabled="{getStyle('disabledImage')}"
                   />
</s:SparkButtonSkin>

ImageSkinnableButton.as

[Style(name="upImage", inherit="no", type="Class")]
[Style(name="downImage", inherit="no", type="Class")]
[Style(name="overImage", inherit="no", type="Class")]
[Style(name="disabledImage", inherit="no", type="Class")]
public class ImageSkinnableButton extends Button
{
    public function ImageSkinnableButton()
    {
        super();
        setStyle("skinClass", ImageButtonSkin);
    }
}

Then you can set the images as styles on the button in either CSS (preferred) or in mxml:

<commons:ImageSkinnableButton
    upImage="@Embed('imgs/mainButton_std.png')"
    overImage="@Embed('imgs/mainButton_over.png')"
    downImage="@Embed('imgs/mainButton_over.png')"
    disabledImage="@Embed('imgs/mainButton_std.png')" />

Solution 2

You can also define a ButtonImageSkin for the default spark.components.Button component, for example in the imageskins package:

<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:fb="http://ns.adobe.com/flashbuilder/2009">
    <fx:Metadata>
        [HostComponent("spark.components.Button")]
    </fx:Metadata>
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
    <s:BitmapImage source="{getStyle('backgroundImage')}"/>
</s:SparkButtonSkin>

Simply define a style on the skin class itself, and bind the source of the image to it. Now, you can control the actual images using CSS pseudo selectors:

@namespace imageskins "imageskins.*";
s|Button {
    skinClass: ClassReference("imageskins.ButtonImageSkin");    
}
imageskins|ButtonImageSkin:up {
    backgroundImage: Embed(source="assets/images/button-up.png");
}
imageskins|ButtonImageSkin:down {
    backgroundImage: Embed(source="assets/images/button-down.png");
}
imageskins|ButtonImageSkin:over {
    backgroundImage: Embed(source="assets/images/button-over.png");
}
imageskins|ButtonImageSkin:disabled {
    backgroundImage: Embed(source="assets/images/button-disabled.png");
}

This way you can obtain the result with more flexible CSS based rules. I ended up creating a set of image-based Spark skins for various Flex components: FXG is way more powerful, but sometimes working with scale9 images is simply the quickest way to obtain the desired result.

Side note: if you put your skin classes and your CSS file (with any name) in a Flex Library Project, and compile your client project with the -theme option, Flex will automatically apply the CSS.. useful when creating a set of skin along with the CSS that associate them with their host components.

Share:
12,773
PicoCreator
Author by

PicoCreator

Updated on June 04, 2022

Comments

  • PicoCreator
    PicoCreator about 2 years

    Anyone missed the old simple method for skinning a simple button?

    <mx:Button x="10" y="10" label=""
               upSkin="@Embed('imgs/mainButton_std.png')"
               overSkin="@Embed('imgs/mainButton_over.png')"
               downSkin="@Embed('imgs/mainButton_over.png')"
               disabledSkin="@Embed('imgs/mainButton_std.png')"
               creationComplete="mainButtonHitArea()"
               width="75" height="75" id="menuButton" enabled="true"/>
    //mainButtonHitArea() : Is a generic function that generates the hit area
    

    The problem im having is that, this method of creating a simple button with skin is being phased out : Infact it is no longer supported in flex 4.5 mobile projects.

    So the question: Is there a simple way to perform this, with spark buttons (which is suppose to be the new way to go). As simple as possible.

    Basically i only need a button with 2 images : down/over & up. And i want to keep the code as simple as possible : The new skinning methods, seems to really adds way too much lines for something that used to be as simple as the example above.