Monday, May 10, 2010

Flex4: Templatizing skins

With Flex4 the convention is to leave the appearance up to the skins but you may sometimes find that you are copy pasting the same skin multiple times with only minor tweaks in them. For example: different gradient colors, thicker/thinner borders etc. One of the most common scenarios is having a consistent button appearance across the app. If you follow Adobe's approach you will end up with multiple button skins containing very few changes. The proposed solution is to move commonly changed properties to a generic component class and then reference those properties in the skin.

Example: you have 2 types of buttons in you app - one with gradient fill and one with solid fill.
One way is to create GradientFillButtonSkin and SolidFillButtonSkin. Wouldn't it be nice to have only one skin and just fill it with what you wish to use - gradient or solid? You can!
<templatebutton>
    <fill><gradientcolor.../></fill>
</templatebutton>
To accomplish this we define a custom class TemplateButton:
TemplateButton extends Button {
...
[Bindable]
var buttonFill:IFill;
and in its respective skin class TemplateButtonSkin (which is probably a copy of spark ButtonSkin), you define a host component and a default fill:
[HostComponent("TemplateButton")]
<fx:declarations>
    <s:lineargradient id="defaultButtonFill">
    </s:lineargradient>
</fx:declarations>
...
<s:rect>
    <s:fill>
        {hostComponent.buttonFill!=null ? hostComponent.buttonFill : defaultButtonFill}
    </s:fill>
</s:rect>
Following this approach you can have with all types of fills: Solid, Linear, Radial, etc. and just use as following
<templatebutton skinclass="TemplateButtonSkin">
<fill>
    <solidfill.../>
</fill>
The same approach can be applied to strokes, (up, over, down states for fill and strokes), styles for text in the button and many others.

0 comments:

Post a Comment