Skinning components in Flex 2 is really easy. Every component has a bunch of skin styles defined. For example, the DataGrid has a "sortArrowSkin" that specifies the skin to use for the sort indicator when a column is sorted. The value of a skin style can either be a reference to an ActionScript class or it can be an embedded graphic (embedded graphics are internally represented as ActionScript classes).
Screenshot: DataGrid with default sort arrow
Let's look at the graphical way of skinning the arrow. I'm going to set the value of the "sortArrowSkin" style to an embedded graphic.
<DataGrid sortArrowSkin="@Embed('heart.gif')" ...
Screenshot: DataGrid with embedded graphic (heart) as sort arrow
That's quick, isn't it?
Graphical skinning is good for simple fixed-size, fixed-colour skins. On the other hand, if a skin must change its look based on its environment (the values of certain styles, the amount of space available for drawing, and so on), programmatic skinning is the way to go.
A programmatic skin is basically an ActionScript class that has the ability to measure and draw itself. The main top-level class for skinning is ProgrammticSkin, a subclass of the player's Shape class. Most programmatic skins are based on the ProgrammaticSkin class.
I'm going to implement a simple sort indicator skin that draws an arrow in the colour specified by the DataGrid's "sortArrowColor" style.
package {
import flash.display.*;
import mx.skins.*;
public class SimpleArrow extends ProgrammaticSkin
{
override public function get measuredWidth():Number
{
return 6;
}
override public function get measuredHeight():Number
{
return 6;
}
override public function updateDisplayList(w:Number, h:Number):Void
{
super.updateDisplayList(w, h);
var g:Graphics = graphics;
var c:uint = getStyle("sortArrowColor");
g.clear();
g.beginFill(c, 1.0);
g.moveTo(0, 0);
g.lineTo(w, 0);
g.lineTo(w / 2, h);
g.lineTo(0, 0);
g.endFill();
}
}
}
My SimpleArrow class extends ProgrammaticSkin and overrides the measuredWidth and measuredHeight getters to return a fixed value of 6. These properties help the DataGrid to decide how to size and position the indicator. In the updateDisplayList implementation, I'm drawing an arrow in the "sortArrowColor" colour.
Here's how it is used:
<Style>
DataGrid {
sortArrowSkin: ClassReference("SimpleArrow");
sortArrowColor: red;
}
<Style>
Screenshot: DataGrid with programmatic skin as sort arrow
All skin styles have names ending in "Skin" (like "sortArrowSkin"), so they are easy to identify.