In this article I will create a custom Spark Button control that will look something like this:

You can find the working example lower on this page.
There are five steps that you must take to create a new Flex 4 Skin (for any Spark component):
- Create a new MXML component that extends the SparkSkin class
- Define the states of the Skin. The default states for most of the Spark Button control are
disabled,down,overandup - Define the HostComponent between Metadata tags
- Specify all the graphical elements that are used by the custom Skin
- Define the skin parts for the skin
The first thing that I did was to create a custom MXML component for the Spark Button skin. I created this component in the skins package and I named the custom skin ButtonSkin.
The next step was to define the states of the skin. To see what states are available for any Spark component you should check out the Adobe ActionScript 3.0 Reference for the Adobe Flash Platform online documentation or the local help. After you have located the Spark Button control in the help files click the Skin states tab and this will take you to Spark Button control states. The online documentation page for the spark button control should look something like this:
I find the online documentation really helpful, and you can use it in this way for any Spark component that you are skinning.
For skinning the Spark Button I used the four default Skin States: disabled, down, over and up.
<s:states> <s:State name="disabled"/> <s:State name="down"/> <s:State name="over"/> <s:State name="up"/> </s:states> |
Next we need to specify the HostComponent between Metadata tags. The HostComponent will be the path to the Spark component that will be skinned. In this case: spark.components.Button:
<fx:Metadata> [HostCompoent("spark.components.Button")] </fx:Metadata> |
The next step is to draw all the graphic for the button:
<s:BorderContainer width="100%" height="100%" maxWidth="100" maxHeight="50" borderColor="#aaaaaa" borderColor.down="#000000" borderColor.over="#777777" borderWeight="3" cornerRadius="8" alpha.disabled="0.3"> <s:Rect width="100%" height="100%" bottomLeftRadiusX="7" bottomLeftRadiusY="7" bottomRightRadiusX="7" bottomRightRadiusY="7" topLeftRadiusX="7" topLeftRadiusY="7" topRightRadiusX="7" topRightRadiusY="7"> <s:fill> <s:LinearGradient rotation="90"> <s:entries> <s:GradientEntry color="#bf0000" color.over="#ff3744" color.down="#3f3f3f"/> <s:GradientEntry color="#ff3744" color.over="#bf0000" color.down="#a5a5a5"/> </s:entries> </s:LinearGradient> </s:fill> </s:Rect> </s:BorderContainer> |
To specify different attribute values for different states you use this notation: borderColor="#aaaaaa" borderColor.down="#000000" borderColor.over="#777777". This will mean that the borderColor in the down state will be #000000, in the over state it will be #777777 and in the rest rest of the states (up and disabled) it will be #aaaaaa.
I used the same technique for the gradient colors and for the label fontSize.
For the disabled skin state I made the entire BorderContainer transparent by setting the alpha property to 0.3:alpha.disabled="0.3".
The last step is to define the skin parts for the Spark Button control. The Spark Button control has one skin part, the labelDisplay which is a TextBase control. This means that we can use a Label control with an id set to labelDisplay to define this skin part:
<s:Label id="labelDisplay" color="#ffffff" width="100%" height="100%" textAlign="center" fontSize="14" fontSize.over="18" fontSize.down="18" fontWeight="bold" fontStyle="italic" verticalAlign="middle" /> |
Ok, that’s all as far as the custom Button Skin is concerned. Now I will focus on the applying the Custom Skin to a few Button instance in the application. One of the instances will be enabled and the other one disabled to see both in action. To apply a Custom Skin to a Spark component you will use skinClass property like this:
<s:Button label="Button" skinClass="skins.ButtonSkin"/> <s:Button label="Button" skinClass="skins.ButtonSkin" enabled="false"/> |
Here is the resulting application:
View Source is enabled in the above example. To view the source files right click on the swf and choose “View Source” from the context menu.
Here is the complete source code for the main application:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" viewSourceURL="srcview/index.html"> <s:Group horizontalCenter="0" verticalCenter="0"> <s:layout> <s:HorizontalLayout/> </s:layout> <s:Button label="Button" skinClass="skins.ButtonSkin"/> <s:Button label="Button" skinClass="skins.ButtonSkin" enabled="false"/> </s:Group> </s:Application> |
And here is the complete source code for the Custom Button Skin Class:
<?xml version="1.0" encoding="utf-8"?> <s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <s:states> <s:State name="disabled"/> <s:State name="down"/> <s:State name="over"/> <s:State name="up"/> </s:states> <fx:Metadata> [HostCompoent("spark.components.Button")] </fx:Metadata> <s:BorderContainer width="100%" height="100%" maxWidth="100" maxHeight="50" borderColor="#aaaaaa" borderColor.down="#000000" borderColor.over="#777777" borderWeight="3" cornerRadius="8" alpha.disabled="0.3"> <s:Rect width="100%" height="100%" bottomLeftRadiusX="7" bottomLeftRadiusY="7" bottomRightRadiusX="7" bottomRightRadiusY="7" topLeftRadiusX="7" topLeftRadiusY="7" topRightRadiusX="7" topRightRadiusY="7"> <s:fill> <s:LinearGradient rotation="90"> <s:entries> <s:GradientEntry color="#bf0000" color.over="#ff3744" color.down="#3f3f3f"/> <s:GradientEntry color="#ff3744" color.over="#bf0000" color.down="#a5a5a5"/> </s:entries> </s:LinearGradient> </s:fill> </s:Rect> </s:BorderContainer> <s:Label id="labelDisplay" color="#ffffff" width="100%" height="100%" textAlign="center" fontSize="14" fontSize.over="18" fontSize.down="18" fontWeight="bold" fontStyle="italic" verticalAlign="middle" /> </s:SparkSkin> |
Commenting and sharing is encouraged.
Enjoy!

why should i need bordercontainer in skin at the first place?) U could use stroke for rect with same result;
also radiusX will set all radius so no need to specify
topLeftRadiusY etc
mzx
13 Nov 11 at 3:14 pm
nice skin and thanks for sharing.
tahir alvi
24 Mar 11 at 4:29 pm
To do that you will have to change the
maxWidthproperty on theBorderContainercontainer inside theButtonSkinclass. In my examplemaxWidthis set to 100. Make it 300 or something that will work for you.Also if the label text on the button gets longer you might have to add some padding on the label. On the
labelDisplayLabel inside theButtonSkinclass add something like this:paddingRight="10" paddingLeft="10"and that should do the trick.
Hope this helps
Cheers,
Mihai
Popa Mihai
1 Feb 11 at 7:00 pm
It’s a great and helpfull example, thank you for your effort.I have only one question: what do i have to add to your ButtonSkin class to get a resizeable button, so that i can make a lot of buttons with different dimensions?If you have the time, i’d appreciate the help, i am new to this so i apologize if it’s a stupid question.
Thanks!
edis
1 Feb 11 at 1:29 pm