Creating Flex View States in ActionScript

In Flex 4, Adobe introduced new MXML language improvements that make it much easier to work with states. This support includes the dot (.) delimiter for specifying state overrides, and the new MXML excludeFrom and includeIn attributes.

The following item renderer, MySimpleCustomItemRendererMXML.mxml in the myComponents subdirectory, uses view states to control the appearance of the items in a SkinnableDataContainer container:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:states>
        <s:State name="normal"/>
        <s:State name="hovered"/>
    </s:states>

    <s:Label id="labelDisplay"
        verticalCenter="0"
        left="3" right="3" top="6" bottom="4"
        fontSize.hovered='14' fontStyle.hovered="italic"/>
</s:ItemRenderer>

The following application uses this item renderer:

<?xml version="1.0" encoding="utf-8"?>
 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
     xmlns:s="library://ns.adobe.com/flex/spark"
     xmlns:mx="library://ns.adobe.com/flex/mx">

    <s:SkinnableDataContainer
        itemRenderer="myComponents.MySimpleCustomItemRendererMXML">
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>

    <mx:ArrayList>
        <fx:String>Bill J Smith</fx:String>
        <fx:String>Dave Jones</fx:String>
        <fx:String>Mary Davis</fx:String>
        <fx:String>Debbie Cooper</fx:String>
        </mx:ArrayList>
    </s:SkinnableDataContainer>
</s:Application>

However, you might also want to create view state in ActionScript, either in an MXML file or in an ActionScript file. The following example uses the creationComplete event to define the view states in ActionScript:

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    xmlns:s="library://ns.adobe.com/flex/spark"
    creationComplete="creationCompleteHandler(event);">

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import mx.states.SetStyle;
            import mx.states.State;

            protected function creationCompleteHandler(event:FlexEvent):void {
                states = [
                    new State({name:"normal"}),
                    new State({name:"hovered",
                        overrides:[
                            new SetStyle(labelDisplay, "fontSize", 14),
                            new SetStyle(labelDisplay, "fontStyle", "italic")]
                        })
                ];
            }
        ]]>
    </fx:Script>

    <s:Label id="labelDisplay"
        verticalCenter="0"
        left="3" right="3" top="6" bottom="4"/>
</s:ItemRenderer>

In this example, you import the mx.states.State and mx.states.SetStyle classes. Every Flex component inherits the mx.core.UIComponent.states property. This property contains an Array of State objects that define the supported view states of the component. In the event handler for the creationComplete event, create an Array of State objects. The name property of the State objects defines the name of the view state.

The State.overrides property contains an Array of objects that implement the mx.states.IOverride interface. The AddChild, AddItems, RemoveChild, SetEventHandler, SetProperty, and SetStyle classes all implement this interface. In this example, you create two instances of SetStyle that override the fontSize and fontStyle styles of the Label control. You can mix objects of type AddChild, AddItems, RemoveChild, SetEventHandler, SetProperty, and SetStyle in the overrides Array.

Note that manipulating at runtime view states, containers that use view states, or properties of components that are controlled by view states can be problematic. For example, when you use view states to control the children of a container, do not add or remove container children, or change the order of children in the container, at runtime. The following container defines a Button control that appear only in State2:

<s:Group>
    <s:Button/>
    <s:Button includeIn="State2"/>
    <s:Button/>
</s:Group>

The view states infrastructure relies on the structure of the container as defined by the MXML file. Changing the child order of the container at runtime can cause your application to fail. Therefore, do not call the addElement(), removeElement(), or setElementIndex() method on the Group container at runtime, or any other method that changes the child order of the container.

For more infomration, see:

 

Stephen Gilson
Flex Doc Team

8 Responses to Creating Flex View States in ActionScript

  1. viebone says:

    If I develop a 100% code app whith flex, how could I add the includeIn property to a dynamic created object, or more complex, how could I set a property like alpha in a especific state if I created all the elements dinamically?????

    Thanks a lot for the post.

  2. Pingback: Adding states at runtime | polyGeek.com

  3. ngeorgiev says:

    I am also interested in writing the “includeIn” property in Actionscript. Is there any way?

  4. SM Gilson says:

    includeIn is built into the MXML compiler and does not have an ActionScript equivelant.

  5. Pingback: Writing flex4 state in Actionscript.

  6. Josef says:

    Very nice blog about view state. It has provided me nice information about view state. Thank you for providing such a good materials.
    I have also gone through following links which are also helpful in case of View State

    http://jksnu.blogspot.com/2011/06/view-state-difference-between-flex3-and.html
    http://jksnu.blogspot.com/2011/06/view-state-difference-between-flex3-and_24.html

  7. Stephen Brown says:

    How would I change an MXML written event by using actionScript, for example how would I change the “click.Info” event here…

    • Stephen Gilson says:

      You can use the SetEventHandler class, much in the same way this example uses the SetStyle class. For example, to set the click event handler for a button named myButton for the hovered state:

      private function handlerInfoState(event:Event):void {
      // Your event handler.
      }

      protected function creationCompleteHandler(event:FlexEvent):void {

      var myEventHandler:SetEventHandler = new SetEventHandler(myButton, ‘click’);
      myEventHandler.handlerFunction = handlerInfoState;

      states = [
      new State({name:”normal”}),
      new State({name:”hovered”,
      overrides:[
      new SetStyle(labelDisplay, “fontSize”, 14),
      new SetStyle(labelDisplay, “fontStyle”, “italic”),
      myEventHandler]
      })
      ];
      }

      myButton is the ID of a button in the app.

      Stephen