| Register
Friday, May 09, 2008   

Controlling Flex UIComponent States in ActionScript 3.0

Created By  Satori Canton, at  8/28/2007 - 1 comments.

Click to view this author's website.

Much of the documentation for Flex development has a heavy focus on implementing Flex applications in MXML. This is great for quick examples, and for structural elements in a large project. But for some projects, you need to know how to implement things in the Flex framework from straight ActionScript.

Recently, we had a project where we needed to be able to control visual states in an application in ActionScript. After looking through the documentation and online resources, I couldn't find any documented implementation of state management in ActionScript. They were all using MXML. So I spent a little time to go through and look at exactly how to control state and transitions via ActionScript.

This is a bit of an advanced topic, so I'm not going to go into FlexBuilder and how to create projects. Assuming a basic familiarity with FlexBuilder, or the Flex SDK, I'm going to show how you can create and control visual states and transitions in ActionScript 3.0.

What we're going to be building is a small application with two forms. The two forms should animate themselves in and out of visual scale between states. This is the example we're going to build (you can right click and select view source to access the source files):

Demo Application | Source Code

If you look a the source files, you'll see that the application is made up of four files. There is the main application MXML file in the root of the project. There are two MXML forms in the com.actionscript.forms package. Each of these forms extend the class "HideScaler" which is located in the com.actionscript.states package.

Let's start by looking at our root application file:

ActionScriptStateTransitions.mxml

This file is used to display the two forms we are about to create, and to add two buttons to allow for some basic interaction to test the changing states between the two forms. As one of the two buttons are clicked, they will call the showName() or showAddress() methods defined in the script tag. These methods will set the currentState of both of our forms.

Our forms are two very basic forms. Since this is just an example, I didn't even give the text fields ids to access their data. These forms are just skeletons for visual display only.

Although our objective is to control states in ActionScript, the forms themselves are a very structural kind of asset, which is where MXML can be very handy when you need to define something in a declarative format.

Form1.mxml

Form2.mxml

Notice that the root tag in both forms are extending a custom class called "HideScaler". This is the class that we will use to implement our custom state and the animated transitions. Since this is where the real action is taking place, let's look at this file in two stages.

HideScaler.as (stage 1)

Our stage 1 look at this class has our basic class definition. HideScaler extends the Flex UIComponent Canvas. As a container, we can use a Canvas to build complex components by composing groups of other components together.

In our constructor, we're calling super() to initialize the Canvas super class and then calling initState() to create the "hide" state of our forms.

We create a new State object, assign it's name property with the name of our state (in this case "hide"). Next we have to add two SetProperty objects to the state overrides array. The overrides array is an assortment of various objects used to change specific aspects of a UIComponent's state. In this case, we're changing the width and height properties, so we can use the mx.states.SetProperty class to manage this change for us. Other classes used for overrides could be mx.states.SetEventHandler and mx.states.SetStyle.

Finally, we push the new state into the states array of our HideScaler (or form) instance so that it will be available when we want to use it.

If we test the application at this point, you'll see that you can now use the buttons to switch between the two visual states of our forms. But you'll notice that the change is an immediate visual change and not a smooth transition and certainly not taking advantage of the rich media experience.

So, let's add a few more lines of code to our initState() method to make our state change look a bit more polished.

HideScaler.as (stage 2)

In order to create the transition animation, we have to set up a few objects. This is where it can get a little confusing, so I've tried to boil this all down to a few basic steps.

The first thing we need to create to animate our state change is a Transition Effect. A transition effect is simply a class that defines how long the transition should last, what UIComponent it should affect and what type of effects it should produce (in our case a Resize).

There are two basic types of transition effects to choose from, Parallel or Sequential. Parallel transition effects animate all children in a UIComponent at the same time (in parallel) and Sequential transitions animate each child in a UIComponent in order (sequentially). Since we only have our one form as a child that will animate, it really doesn't matter which we choose in this case. So, we went with Parallel.

var transEffect:Parallel = new Parallel(this);
transEffect.duration = 400;
transEffect.children.push(new Resize(this));

This first line creates a new Parallel transition effect and provides a reference to this class to it's constructor so that it will affect this particular class. We then set the duration of the transition to 400 milliseconds.

Next, we push a new Resize object (this is the class that manages the tweening of our "height" and "width" changes defined in our SetProperty objects). Check out the classes in the mx.effects package to see other objects (aside from Resize) that can be used to animate other properties of a UIComponent.

The last object we need to instantiate is our actual Transition object. This is the object that ties our state, our effect, our UIComponent all together to create an animated transition.

var stateTransition:Transition = new Transition();
stateTransition.toState = stateTransition.fromState = "*";
stateTransition.effect = transEffect;

This code creates a new Transition instance. We set both the toState and fromState to "*" to apply this transition to all states this class may be displayed in. If we wanted to use two different transitions between two different states, we could customize this transition and add additional ones to handle those specific cases.

The last line of code in this section assigns our Parallel transition effect to the "effect" property of our transition.

Lastly, we push our new transition into the "transitions" array of our class:

transitions.push(stateTransition);

That's pretty much it. If you run the application now, you should see a nice smooth resize animation between the two states.

Conculsion

State management and transitions don't get the same attention to us as developers as some of the other hard-core capabilities of ActionScript 3.0 and Flex2. But with just a few lines of code, you can turn a fairly drab application into a very rich media experience. You don't have to be a super designer/animator to take advantage of this free eye-candy in your projects. Most of all, your clients will absolutely love it!

Need Professional Help For Your ActionScript Project?
ActionScript.com Consulting Services provide top quality professional ActionScript consulting to businesses around the globe. If you have a professional project in need to world-class talent, tell us about your project by requesting a quote today.

Reader Comments

  1. Bijay Rungta  Replied:
    ( 9/7/2007 At 1:12 PM)

    But we still have to know how many items we want to display.

    Isn't there a way through which We can generate and add n number of Form Controls (virtually any content) depending on some input?

    I have a requirement where I don't know in advance how many controls there are goonna be in the Flex App.

    I want to parse an xml file which is again generated dynamically in the server side and generate/add form controls to my App accordingly.

    Any work around for this??

Login to post your comments. If you do not have an account with us please Register.
Copyright 2005 by ActionScript, Inc.   |  Privacy Statement  |  Terms Of Use  |  ActionScript Client Extranet