I’ve been doing a lot of Flex skinning recently so expect a few posts about that over the next few days. This is the first.

There’s not a lot written about using text fields (or any other display object) in a programmatic skin. What there is often suggests you have to add the text field as a child of the skin’s parent. But it’s actually a lot simpler than that.

Skin’s can be sprites

Skin’s don’t have to be shapes. A skin can be any display object. It’s just that the ProgrammaticSkin base class, and all the halo skins, are shapes. But a skin can be a Sprite, for example, or even a MovieClip, or a Loader, or whatever.

I couldn’t find any documentation on what interfaces a skin must implement, but as far as I can tell IFlexDisplayObject is the only essential one (even IProgrammaticSkin is optional). Looking at the ProgrammaticSkin class you’ll notice that it extends FlexShape and implements a number of interfaces, including the important IFlexDisplayObject.

To make skins that are sprites, all we need is a programmatic skin base class that’s a sprite. And the easiest way to achieve that is to duplicate the ProgrammaticSkin class and alter it to extend FlexSprite rather than FlexShape.

...
public class ProgrammaticSpriteSkin extends FlexSprite
                  implements IFlexDisplayObject, IInvalidating,
                  ILayoutManagerClient, ISimpleStyleClient,
                  IProgrammaticSkin
{...

That’s all there is to it. Now, extend this class to create a skin, and then use addChild to add display objects to the skin’s display list. For example

package
{
  import flash.text.TextField;
  import flash.text.TextFormat;

  public class SkinWithText extends ProgrammaticSpriteSkin
  {
    private var textField:TextField;
    
    public function SkinWithText()
    {
      super();
    }

    override protected function updateDisplayList(
                              w:Number, h:Number ):void 
    {
      graphics.clear();
      graphics.beginFill( 0x000000, 1 );
      graphics.drawEllipse( 0, 0, w, h );
      graphics.endFill();

      if( !textField )
      {
        textField = new TextField();
        
        var tf:TextFormat = new TextFormat();
        tf.font = "Georgia";
        tf.size = Math.floor( h * 0.8 );
        tf.color = 0xFFFFFF;
        tf.align = "center";
        tf.bold = true;
        tf.italic = true;
        textField.defaultTextFormat = tf;
        
        textField.text = "i";
        textField.width = w;
        textField.height = h;
        
        addChild( textField );
      }
    }
  }
}