MX ViewStack navigator container

A ViewStack navigator container is made up of a collection of child containers that are stacked on top of each other, with only one container visible, or active, at a time. The ViewStack container does not define a built-in mechanism for users to switch the currently active container; you must use a LinkBar, TabBar, ButtonBar, or ToggleButtonBar control or build the logic yourself in ActionScript to let users change the currently active child. For example, you can define a set of Button controls that switch among the child containers.

The following image shows the stacked child containers in a ViewStack container:

View full size graphic
A.
Child container 1 active

B.
Child container 0 active

On the left, you see a ViewStack container with the first child active. The index of a child in a ViewStack container is numbered from 0 to n - 1, where n is the number of child containers. The container on the right is a ViewStack container with the second child container active.

For complete reference information, see ViewStack in the ActionScript 3.0 Reference for the Adobe Flash Platform.

Creating a ViewStack container

You use the <mx:ViewStack> tag to define a ViewStack container, and you define the child containers in the tag body. You use the following properties of the ViewStack container to control the active child container:

selectedIndex
The index of the currently active container if one or more child containers are defined. The value of this property is -1 if no child containers are defined. The index is numbered from 0 to numChildren ‑ 1, where numChildren is the number of child containers in the ViewStack container. Set this property to the index of the container that you want active.

You can use the selectedIndex property of the <mx:ViewStack> tag to set the default active container when your application starts. The following example sets the index of the default active container to 1:

<mx:ViewStack id="myViewStack" selectedIndex="1">

The following example uses ActionScript to set the selectedIndex property so that the active child container is the second container in the stack:

myViewStack.selectedIndex=1;

selectedChild
The currently active container if one or more child containers are defined. The value of this property is null if no child containers are defined. Set this property in ActionScript to the identifier of the container that you want active.

You can set this property only in an ActionScript statement, not in MXML.

The following example uses ActionScript to set the selectedChild property so that the active child container is the child container with an identifier of search:

myViewStack.selectedChild=search;

numChildren
Contains the number of child containers in the ViewStack container.

The following example uses the numChildren property in an ActionScript statement to set the active child container to the last container in the stack:

myViewStack.selectedIndex=myViewStack.numChildren-1;
Note: The default creation policy for all containers, except the Application container, is the policy of the parent container. The default policy for the Application container is auto. In most cases, therefore, the View Stack control’s children are not created until they are selected. You cannot set the selectedChild property to a child that is not yet created.

The following example creates a ViewStack container with three child containers. The example also defines three Button controls that when clicked, select the active child container:

<?xml version="1.0"?>
<!-- containers\navigators\VSSimple.mxml  -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <!-- Create a VGroup container so the container for 
        the buttons appears above the ViewStack container. -->
    <s:VGroup>
        <!-- Create an HBox container to hold the three buttons. -->
        <mx:HBox borderStyle="solid">

            <!-- Define the three buttons. 
                Each uses the child container identifier 
                to set the active child container. -->
            <s:Button id="searchButton" 
                label="Search Screen" 
                click="myViewStack.selectedChild=search;"/>

            <s:Button id="cInfoButton" 
                label="Customer Info Screen" 
                click="myViewStack.selectedChild=custInfo;"/>

            <s:Button id="aInfoButton" 
                label="Account Info Screen"
                click="myViewStack.selectedChild=accountInfo;"/>
        </mx:HBox>

        <!-- Define the ViewStack and the three child containers and have it
            resize up to the size of the container for the buttons. -->
        <mx:ViewStack id="myViewStack" 
            borderStyle="solid" width="100%">

            <mx:Canvas id="search" label="Search">
                <mx:Label text="Search Screen"/>
            </mx:Canvas>

            <mx:Canvas id="custInfo" label="Customer Info">
                <mx:Label text="Customer Info"/>
            </mx:Canvas>

            <mx:Canvas id="accountInfo" label="Account Info">
                <mx:Label text="Account Info"/>
            </mx:Canvas>
        </mx:ViewStack>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

When this example loads, the three Button controls appear, and the first child container defined in the ViewStack container is active. Select a Button control to change the active container.

You can also use an MX LinkBar, TabBar, ButtonBar, or ToggleButtonBar control or the Spark ButtonBar or TabBar control to set the active child of a ViewStack container. These controls can determine the number of child containers in a ViewStack container, and then create a horizontal or vertical set of links, tabs, or buttons that let the user select the active child, as the following image shows:

Child containers in a ViewStack container

The items in the LinkBar control correspond to the values of the label property of each child of the ViewStack container, as the following example shows:

<?xml version="1.0"?>
<!-- containers\navigators\VSLinkBar.mxml -->
<s:Application 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:VGroup>
        <!-- Create a LinkBar control to navigate 
            the ViewStack container. -->
        <mx:LinkBar dataProvider="{myViewStack}" borderStyle="solid"/>

        <!-- Define the ViewStack and the three child containers. -->
        <mx:ViewStack id="myViewStack" 
            borderStyle="solid" 
            width="100%">
            
            <mx:Canvas id="search" label="Search">
                <mx:Label text="Search Screen"/>
            </mx:Canvas>

            <mx:Canvas id="custInfo" label="Customer Info">
                <mx:Label text="Customer Info"/>
            </mx:Canvas>

            <mx:Canvas id="accountInfo" label="Account Info">
                <mx:Label text="Account Info"/>
            </mx:Canvas>
        </mx:ViewStack>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

You provide only a single property to the navigator bar control, dataProvider, to specify the name of the ViewStack container associated with it. For more information on the LinkBar control, see LinkBar control. For more information on the TabBar control, see MX TabBar control. For more information on the ButtonBar and ToggleButtonBar controls, see MX ButtonBar and MX ToggleButtonBar controls.

You can also use the Spark ButtonBar control to set the active child of a ViewStack container, as the following example shows:
<?xml version="1.0"?>
<!-- containers\navigators\VSSparkButtonBar.mxml -->
<s:Application 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:VGroup>
        <!-- Create a Spark ButtonBar control to navigate 
            the ViewStack container. -->
        <s:ButtonBar dataProvider="{myViewStack}"/>

        <!-- Define the ViewStack and the three child containers. -->
        <mx:ViewStack id="myViewStack" 
            borderStyle="solid" 
            width="100%">
            
            <s:NavigatorContent id="search" label="Search">
                <s:Label text="Search Screen"/>
            </s:NavigatorContent>

            <s:NavigatorContent id="custInfo" label="Customer Info">
                <s:Label text="Customer Info"/>
            </s:NavigatorContent>

            <s:NavigatorContent id="accountInfo" label="Account Info">
                <s:Label text="Account Info"/>
            </s:NavigatorContent>
        </mx:ViewStack>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

For more information on the Spark ButtonBar control, see the Spark ButtonBar and TabBar controls.

Sizing the children of a ViewStack container

The default width and height of a ViewStack container is the width and height of the first child. A ViewStack container does not change size every time you change the active child.

You can use the following techniques to control the size of a ViewStack container so that it displays all the components inside its children:

  • Set explicit width and height properties for all children to the same fixed values.

  • Set percentage-based width and height properties for all children to the same fixed values.

  • Set width and height properties for the ViewStack container to a fixed or percentage-based value.

    The technique that you use is based on your application and the content of your ViewStack container.

Applying effects to a ViewStack container

You can assign effects to the ViewStack container or to its children. For example, if you assign the WipeRight effect to the creationCompleteEffect property of the ViewStack control, Flex plays the effect once when the ViewStack first appears.

To specify the effects that run when the ViewStack changes children, use the children’s hideEffect and showEffect properties. The effect specified by the hideEffect property plays as a container is being hidden, and the effect specified by the showEffect property plays as the newly visible child appears. The ViewStack container waits for the completion of the effect specified by the hideEffect property for the container that is being hidden before it reveals the new child container.

The following example runs a WipeRight effect when the ViewStack container is first created, and runs a WipeDown effect when each child is hidden and a WipeUp effect when a new child appears.

<?xml version="1.0"?>
<!-- containers\navigators\VSLinkEffects.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Declarations>
        <mx:WipeUp id="myWU" duration="300"/>
        <mx:WipeDown id="myWD" duration="300"/>
        <mx:WipeRight id="myWR" duration="300"/>
    </fx:Declarations>

    <s:VGroup>
        <mx:LinkBar dataProvider="{myViewStack}" 
            borderStyle="solid"
            backgroundColor="#EEEEFF"/>

        <mx:ViewStack id="myViewStack" 
            borderStyle="solid" 
            width="100%"
            creationCompleteEffect="{myWR}">

            <mx:Canvas id="search" 
                label="Search"
                hideEffect="{myWD}" 
                showEffect="{myWU}">
                <mx:Label text="Search Screen"/>
            </mx:Canvas>

            <mx:Canvas id="custInfo" 
                label="Customer Info"
                hideEffect="{myWD}" 
                showEffect="{myWU}">
                <mx:Label text="Customer Info"/>
            </mx:Canvas>

            <mx:Canvas id="accountInfo" 
                label="Account Info"
                hideEffect="{myWD}" 
                showEffect="{myWU}">
                <mx:Label text="Account Info"/>
            </mx:Canvas>
        </mx:ViewStack>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

Notice that the showEffect property of a container is only triggered when the container’s visibility changes from false to true. Therefore, you use the creationCompleteEffect property to trigger the effect when Flex first creates the component.