Managing States in Flex 4 Containers Using ActionScript

Written by

Following reading this fantastic article a while back I totally immersed myself in getting the segregation of component logic and layout truly separated in my Flex 4 projects. One obstacle I came up against, particularly using Justin’s method, was states in my newly created component which extended a container. Now Justin has another great post in regards to states and skins, but this is specific to mxml and the container extends SkinnableContainer.as (Application in this particular link).

So whats the problem? Well obviously if you want to start defining custom states in your component and mapping them accordingly to your component skin, these states need to be declared somewhere and added to the states array (see here again to see what I mean). What I needed to do was grab the snippets of information on the web and then duplicate this logic into my container class accordingly. Here is what I ended up with:

CustomContainer - add SkinState metadata

1
2
3
[SkinState("loading")]
[SkinState("initialised")]
public class CustomContainer extends SkinnableContainer

CustomContainer - override initialize method and add custom states to states array (doesn’t have to be initialize, just what I thought to be the best method override)

1
2
3
4
5
6
public override function initialize():void
{
    super.initialize();
    states.push(new State({name:"loading"}));
    states.push(new State({name:"initialised"}));
}

CustomContainer - override stateChanged method to ensure the skin states get invalidated

1
2
3
4
5
override protected function stateChanged(oldState:String, newState:String, recursive:Boolean):void
{
    super.stateChanged(oldState, newState, recursive);
    invalidateSkinState();
}

CustomContainer - override getCurrentSkinState method returning the hosts skin state

1
2
3
4
protected override function getCurrentSkinState():String
{
    return currentState;
}

CustomSkin - add your new states to your skin

1
2
3
4
<s:states>
     <s:State name="loading" />
     <s:State name="initialised" />
</s:states>

Now you should be able to access your states in your component and skin as per normal.

Comments