Here's an extended version of the Flex Cookbook recipe I posted the other day.
The Flex 2 ViewStack and TabNavigator controls make it easy to manage multiple views in a Flex 2 application. Each view container becomes a child of the ViewStack (which is the superclass of the TabNavigator). You can access a specific view by index using the selectedIndex property, or by matching against the view object itself using the selectedChild property.
However I don't like to use index values to identify the views. Index values might change if the order of the views changes. Index values have no real meaning so they are hard to remember. I prefer to set up a method that lets other components or code request a view change by a meaningful name, like the id of the view. That way the other components or code in the application don't need to care about the order of the views in the ViewStack; they just need to know the id of the view to show.
Here is some code that does just that:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical" >
<mx:Script>
<![CDATA[
import mx.core.Container;
import mx.events.IndexChangedEvent;
/**
* Looks through the views in the stack to find one whose id matches,
* then switches to it. This will fire the the ViewStack's change event.
*/
public function switchView(viewId:String):void
{
var container:Container = Container(nav.getChildByName(viewId));
if (container != null)
{
nav.selectedChild = container;
}
}
/**
* Called when the selected component in the ViewStack changes.
*/
public function onViewChange(evt:IndexChangedEvent):void
{
var panel:Panel = nav.getChildAt(evt.newIndex) as Panel;
panel.title = panel.id + " selected.";
}
]]>
</mx:Script>
<mx:HBox width="100%">
<mx:Button id="btn1" width="150" label="switchView('panel1')" click="switchView('panel1');" />
<mx:Button id="btn2" width="150" label="switchView('panel2')" click="switchView('panel2');" />
<mx:Button id="btn3" width="150" label="switchView('panel3')" click="switchView('panel3');" />
</mx:HBox>
<mx:ViewStack id="nav" width="100%" height="100%" change="onViewChange(event)">
<mx:Panel id="panel1" label="Panel One" width="100%" height="100%" backgroundColor="#CCCCEE" />
<mx:Panel id="panel2" label="Panel Two" width="100%" height="100%" backgroundColor="#EECCCC" />
<mx:Panel id="panel3" label="Panel Three" width="100%" height="100%" backgroundColor="#CCEECC" />
</mx:ViewStack>
</mx:Application>
The core of this solution is the switchViews() method that accepts an id string as a parameter. The switchViews() method finds the right child container of the ViewStack or TabNavigator object and then switches to it.
Click any of the buttons to switch views based on the component id. You can switch views from anywhere else in your scripts just by calling switchView('viewId').
This example also shows how to call a common method when the view is switched, using the change property of the ViewStack to call the onViewChange() method when the CHANGE event is fired. In the onViewChange() method, it gets a reference to the newly-displayed container using the getChildAt() method and the newIndex property of the event.
Can't you just use ViewStack.selectChild( id ) to do exactly that?
Posted by: Daniel Wood | 15 April 2007 at 05:27 AM
I am new to Flex. I tried your example using a button with ...click="switchView('name of container');"/> from a component. The result was an 1180 error: "Call to a possibly undefined method switchView." In an earlier post you said this could be used from a component. I would appreciate an explanation or example of the correct way to use this from a component. Thank you for your help.
Posted by: Bill Graham | 25 November 2007 at 07:52 PM