There are a lot of articles and blogs online which talk about how to write programmatic skins, but these skins can only be seen when the Flex application actually runs. What do I need to do if I want to see the applied programmatic skin in the Flex Builder Design view, so i can play around with my layout?
There are some steps that need to be followed. And what better way there is to show the examples? I wish this blogging site supported code snippets, but it doesnt , so i will provide links to code.
The Application mxml is ProgrammaticSkinning.mxml and the skin classes are FlatColorRectangleSkin.as , FlatColorRoundedRectangleSkin.as, GradientRectangleSkin.as and NodeSkin.mxml.
The custom class is Node.as and the style sheet is styles.css. The code in these classes is straight forward, so i wont explain them all. But Node.as and NodeSkin.mxml are special.
1. Node.as should be put in a different library project, if this class exists in the same project, the skins wont be rendered in Flex Builder design view. I dont know the reason for this, if anybody knows, please let me know.
2. Node class in order to support skins, has to override updateDisplayList method, get the SkinClass, create an instance of the class, set the skin Name , set stylename on the skin to this(for the skin to inherit all style properties from the component), set the size of the skin to the component or appropriate (we want the size of skin to be grater than 0, to be able to see it), and add the skin as a child.
3. If anyone wants to use Degrafa for skinning, look at NodeSkin.mxml. This is my favourite. We can use Degrafa tags to define our tags.
That said, we can create our custom components, style them in any way we want, use them in Flex Builder, drag-n-drop in Flex Builder design view and play with the layout.
Also, here is a component you can extend form if you want your component to be skinnable.
package charts
{
import flash.display.DisplayObject;
import flash.events.MouseEvent;
import mx.core.IFlexDisplayObject;
import mx.core.UIComponent;
import mx.effects.Zoom;
import mx.effects.easing.Bounce;
import mx.styles.ISimpleStyleClient;
public class SkinnableComponent extends UIComponent
{
private var zoomAll:Zoom = new Zoom();
public function SkinnableComponent()
{
scaleX = 0.5;
scaleY = 0.5;
addEventListener(MouseEvent.ROLL_OVER, doZoom);
addEventListener(MouseEvent.ROLL_OUT, doZoom);
zoomAll.zoomWidthTo = 1;
zoomAll.zoomHeightTo =1;
zoomAll.zoomWidthFrom = 0.5;
zoomAll.zoomHeightFrom = 0.5;
}
protected override function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
showSkin("upSkin");
}
protected function showSkin(skinName:String):void
{
var skinClass:Class = Class(getStyle(skinName));
var skin:IFlexDisplayObject = IFlexDisplayObject(getChildByName(skinName));
if (!skin)
{
if (skinClass)
{
skin = IFlexDisplayObject(new skinClass());
skin.name = skinName;
(skin as ISimpleStyleClient).styleName = this;
addChild(DisplayObject(skin));
skin.setActualSize(unscaledWidth, unscaledHeight);
}
}
}
protected function doZoom(event:MouseEvent):void
{
if (zoomAll.isPlaying)
zoomAll.reverse();
else
zoomAll.play([event.target], event.type == MouseEvent.ROLL_OUT ? true : false);
}
}
}
Comments, advices and help are always welcome.