The new Flex 4 skinning architecture makes it easier for developers to completely change the look and feel of an application, while providing better separation between components and their skins.
In this blogpost, by using FXG and the new states syntax, we’ll write a basic MXML skin that reflects it’s hostcomponent states.
For those of you wondering what FXG is:
Flash XML Graphics is a declarative XML syntax, based on SVG for defining vector graphics in applications built with Flex. FXG can also be used as an interchange format with other Adobe tools such as Illustrator, Photoshop or Fireworks, meaning designers can create vector images using those tools and export them as an FXG document.
FXG documents cannot reference other FXG documents or MXML documents.
The FXG specification by Adobe can be found here
Let’s start off
Let’s start off by creating a new Flex project ‘blog_skinstates’, and creating some folders for organisational purposes. I’m using Flash Builder 4.5 as my IDE of choice, but you can use any program you’re most comfortable working with.
In the root src folder, create 2 folders named components and images.
While your at it, add 3 images to the images folder. (I added waffles.jpg, fries.jpg & chocolate.jpg)
In the newly created components, add a new subfolder skins. The folder naming speaks for itself.
After the creation of our folder structure, we create a new custom component named MyCustomComponent.mxml based on s:SkinnableComponent. Place the file in your components folder.
Once this is done, your project’s folder structure should look like this:

Now let’s get our code on!
Defining skin states
Each skinnable component in Spark has a set of skin states. You can change the appearance of your skin based on what skin state the component is in. For a Button, there are four basic skin states: up, over, down, and disabled. You can modify the skin to have a different appearance in each of these states
Skin states are not the same as component states. A component state can change without the skin state changing. In other words, component states are decoupled from skin states. Component states define changes to the behavioral state of a component, while Skin states define changes to the display state of the component that they are attached to.
Open MyCustomComponent.mxml and define all the states you need as MXML tags and as Metadata.
Add an enterState function property to your MXML state tags, which refers to the invalidateSkinState() method. The invalidateSkinState() method is what invalidates the skin state, and sets the skin’s state to that which is returned by the getCurrentSkinState() method.
<fx:Metadata> [SkinState("waffles")] [SkinState("fries")] [SkinState("chocolate")] </fx:Metadata> <s:states> <s:State name="waffles" enterState="invalidateSkinState()" /> <s:State name="fries" enterState="invalidateSkinState()" /> <s:State name="chocolate" enterState="invalidateSkinState()" /> </s:states>
The reason we have to declare the states twice (MXML & Metadata), is both declarations unfortunately serve different purposes.
Secondly, override your MyCustomComponent.xml getCurrentSkinState() method:
<fx:Script> <![CDATA[ override protected function getCurrentSkinState():String{ return currentState; } ]]> </fx:Script>
The skin will use this function to determine which state it’s hostcomponent is in.
Now our custom component is ready, let’s get skinning!.
Creating a skin
Adobe Flash Builder allows us to create skins based on a (custom) component’s implementation. If you select ‘MyCustomComponent’ as your Host component via the ‘Browse’ button in your new MXML Skin dialog, Flash Builder will generate the right Metadata & state tags for you.
If you want to know how, right click on your ‘skins’ folder > new > MXML Skin opens up your new ‘MXML Skin’ dialog:

If you haven’t got Flash Builder, no sweat, just add a new MyCustomComponentSkin.mxml file to your skins folder and make sure your code looks like this:
<?xml version="1.0" encoding="utf-8"?> <s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <!-- host component --> <fx:Metadata> [HostComponent("components.MyCustomComponent")] </fx:Metadata> <!-- states --> <s:states> <s:State name="waffles" /> <s:State name="fries" /> <s:State name="chocolate" /> </s:states> </s:Skin>
The Host Component
The host component meta tag states what component this skin defines, also giving you access to the styles and properities inherit to the specific component.
<fx:Metadata> [HostComponent("components.MyCustomComponent")] </fx:Metadata>
The States
The states declared in your skin, reflect those declared in your Hostcomponent.
<s:states> <s:State name="waffles" /> <s:State name="fries" /> <s:State name="chocolate" /> </s:states>
The Skin content
Let’s add some content to our skin. I’m adding a rectangular shape, an image and a label:
<s:Rect left="0" right="0" top="0" bottom="0"> <s:fill> <s:SolidColor color.waffles="0xFF0000" color.fries="0x00FF00" color.chocolate="0x0000FF"/> </s:fill> </s:Rect> <s:BitmapImage source.fries="@Embed(source='../../images/fries.jpg')" source.waffles="@Embed(source='../../images/waffles.jpg')" source.chocolate="@Embed(source='../../images/chocolate.jpg')" left="10" right="10" top="10" bottom="10" width="250" height="250"/> <s:Label id="labelDisplay" color="0xFFFFFF" verticalCenter="0" horizontalCenter="0" text="{hostComponent.currentState}" fontSize="45" fontWeight="bold"/>
As you can see, we defined a different fill color and image for each state in our skin (waffles, fries, chocolate).
By using binding, we can refer to our Host component’s properties.
The Application
As one of our final steps, we add our MyCustomComponent.mxml to our Application. We’re going to control it’s state by using a predefined ArrayList. Every time it’s selection changes, we’re going to update our component’s state.
This is what the code looks like:
<?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" xmlns:components="components.*" minWidth="955" minHeight="600" viewSourceURL="http://www.multimediacollege.be/swfexamples/skinstates/srcview/index.html"> <fx:Script> <![CDATA[ import spark.events.IndexChangeEvent; protected function stateSelector_changeHandler(event:IndexChangeEvent):void { myComponent.currentState = stateSelector.selectedItem; } ]]> </fx:Script> <s:layout> <s:VerticalLayout gap="10" paddingBottom="10" paddingLeft="10" paddingRight="10" paddingTop="10" /> </s:layout> <s:DropDownList id="stateSelector" width="250" height="25" selectedIndex="0" change="stateSelector_changeHandler(event)"> <s:ArrayList source="['waffles','fries','chocolate']" /> </s:DropDownList> <components:MyCustomComponent id="myComponent" skinClass="components.skins.MyCustomComponentSkin" width="250" height="250" /> </s:Application>
Assigning your skin to the component
The final step is assigning our skin to our component, this can be done in different ways:
1. Directly on the component:
<components:MyCustomComponent id="myComponent" skinClass="components.skins.MyCustomComponentSkin" width="250" height="250" />
2. Via a declaration in a CSS stylesheet:
components|MyCustomComponent { skinClass: ClassReference("components.skins.MyCustomComponentSkin"); }
End result
View source is enabled, so you can take a look at the code or download the whole project file
This may seem a bit complicated at first, but as you begin to develop your own custom Flex 4 components, it will quickly become apparent that this is a very valuable architectural change.
