Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
919,04 KB
Nội dung
Chapter 16: Managing Application Navigation
471
recalculated and rendered anew on each visit to the page. The browser offers caching of
image and other assets to speed up this process, but graphical presentation in a Web
page is necessarily limited.
l
HTML and JavaScript aren’t interpreted identically by every Web browser. In fact,
one of the most costly and time-consuming aspects of classic Web application develop-
ment is testing, because you must test your application on each combination of operating
system, browser, and version that you want to support. Some Web application vendors
handle this issue by limiting the platforms on which an application is supported. For
example, Intuit’s QuickBooks Online, while a powerful and reliable Web application, is
supported only on Microsoft Internet Explorer on Windows and Safari on Mac — no
Firefox users allowed!
Understanding Flex Navigation
Navigation in Flex applications is handled at two levels with navigator containers and view states.
The difference between these strategies can be described as one of the amount of visual change
during a move from one presentation to another:
l
Navigator containers. Use these when you want to replace a rectangular region of a Flex
application (a view) with a completely different visual presentation.
l
View states. Use these when you want to modify an existing view, by adding or removing
visual components or by changing components’ properties, styles, or event listeners.
In some cases, either a navigator container or a view state can get the job done, but for the most
part the choice is clear: Use a navigator container to move from one view to another, and use a
view state to change an existing view.
Cross-Reference
Detailed information about view states is available in Chapter 13.
n
Using Navigator Containers
You create a stack of views using one of the navigator containers provided in the Flex framework.
The
ViewStack class is the simplest of these navigator containers. You declare the ViewStack
container as a parent container that nests a collection of view components and displays only one of
its nested views at any given time.
The
ViewStack container doesn’t have any user interface controls that enable the user to select a
current view, so it’s typically controlled either with ActionScript code or with navigator bar com-
ponents that use the
ViewStack as a data provider and dynamically generate interactive compo-
nents to control navigation.
22_488959-ch16.indd 47122_488959-ch16.indd 471 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Part II: Designing Flex Applications
472
Declaring a ViewStack in MXML
To create a ViewStack in MXML, declare an <mx:ViewStack> tag set. Then declare each
nested container within the
<mx:ViewStack> tag set. You can nest either pre-built containers
from the Flex framework or your own custom components. The containers you nest within the
ViewStack can be either layout or navigator containers.
New Feature
The ViewStack, TabNavigator, and Accordion navigator containers were originally designed so they
could only contain instances of the original MX container classes such as
VBox, HBox, and Panel. This rule is
enforced via the nested object’s inheritance hierarchy: Each of the components nested directly within a
ViewStack must include mx.core.Container as one of its superclasses. If you nest most Spark compo-
nents directly in a
ViewStack, a type coercion error is generated at runtime when the framework tries to cast
the object as
Container.
To solve this, nest the Spark component inside a new component named NavigatorContent. This container
implements a new interface named
INavigatorContent, making it compatible with the MX navigator con-
tainers. To use Spark containers in a
ViewStack (or in its related navigator containers, TabNavigator and
Accordion), nest them in an instance of NavigatorContent.
n
Each container nested within a navigator container, whether implemented as a ViewStack,
TabNavigator, or Accordion, should have a label property. The label is an arbitrary
String that’s used in many circumstances to describe the container’s purpose to the user. You
don’t always need the
label property, but if you bind the stack to a navigator container that gen-
erates interactive components such as
Buttons, or if you use the TabNavigator or
Accordion containers, the value of each nested container’s label is displayed on the interactive
component that navigates to that child container.
This code creates a
ViewStack with five views or layers:
<mx:ViewStack id=”views”>
<mx:HBox/>
<mx:VBox/>
<mx:Canvas/>
<s:NavigatorContent>
<s:Panel/>
<s:/NavigatorContent>
<views:MyCustomComponent/>
</mx:ViewStack>
The first three views are instances of MX containers, the fourth is a Spark Panel wrapped in
NavigatorContent, and the last is an instance of a custom component that’s extended from a
compatible container component.
Using custom components in a navigator container
The views nested within a navigator container can be defined as custom components in MXML.
As described previously, a custom component that’s nested in a navigator container must extend
22_488959-ch16.indd 47222_488959-ch16.indd 472 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 16: Managing Application Navigation
473
either the Spark NavigatorContent component or one of the MX container classes. These
include
HBox, VBox, Canvas, Panel, Form, and others.
The custom component in Listing 16.1 displays a
Label control and a DataGrid wrapped in a
NavigatorContent container.
LISTING 16.1
A custom component suitable for use in a navigator container
<?xml version=”1.0” encoding=”utf-8”?>
<s:NavigatorContent xmlns:fx=”http://ns.adobe.com/mxml/2009”
xmlns:s=”library://ns.adobe.com/flex/spark”
xmlns:mx=”library://ns.adobe.com/flex/mx”
width=”400” height=”300”>
<s:layout>
<s:VerticalLayout horizontalAlign=”center”/>
</s:layout>
<s:Label text=”Author List” styleName=”logo”/>
<mx:DataGrid>
<mx:columns>
<mx:DataGridColumn dataField=”title” headerText=”First Name”/>
<mx:DataGridColumn dataField=”price” headerText=”Last Name”/>
</mx:columns>
</mx:DataGrid>
</s:NavigatorContent>
On the Web
The code in Listing 16.1 is available in the Web site files as views/Authors.mxml in the chapter16 proj-
ect. View components named
Books.mxml and ShoppingCart.mxml are also used in these examples.
n
Creating a ViewStack in Design mode
You can use Flash Builder’s Design mode to visually create a ViewStack and its nested views. As
described previously, each of the nested views must be a container, as an instance of either a Flex
framework container class or a custom component that includes the
Container class in its inher-
itance hierarchy.
Note
Flash Builder’s Design mode refers to the layers of a ViewStack as panes, and the documentation sometimes
refers to them as panels. These terms refer to the nested view containers within the
ViewStack.
n
On the Web
The steps in this section assume that you’ve downloaded the files from the Web site and imported the
chapter16 project.
n
22_488959-ch16.indd 47322_488959-ch16.indd 473 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Part II: Designing Flex Applications
474
Follow these steps to create a ViewStack in Design mode:
1. Open BookStore.mxml from the chapter16 project. Notice that the application
already has an instance of a custom
Header component and a few layout settings:
<?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”
xmlns:views=”views.*”>
<s:layout>
<s:VerticalLayout horizontalAlign=”left”
paddingTop=”20” paddingLeft=”20”/>
</s:layout>
<fx:Style source=”assets/styles.css”/>
<views:Header/>
</s:Application>
2. Run the application. As shown in Figure 16.1, you should see that the Header compo-
nent displays an image, some text, and a background image.
3. Return to Flash Builder, and switch to Design mode.
FIGURE 16.1
The starting application with a custom Header component
22_488959-ch16.indd 47422_488959-ch16.indd 474 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 16: Managing Application Navigation
475
4. Look in the Components view’s Navigators section, and drag a ViewStack into the
application below the header. As shown in Figure 16.2, the
ViewStack is represented
visually by a rectangular outlined area and a toolbar with
+ and – buttons to add and
remove views, and
< and > buttons to navigate from one view to the next.
FIGURE 16.2
A starting ViewStack
Previous
view
Add view
Next view
Remove view
The ViewStack
5. Click the + button to add a new view to the ViewStack. As shown in Figure 16.3,
the Insert Pane dialog box prompts you to select a component to instantiate as a layer of
the
ViewStack. The list of available components includes all containers from the Flex
framework and all the application’s custom components that are eligible for use in the
context of a navigator container.
6. Set the Label of the new pane as Catalog.
22_488959-ch16.indd 47522_488959-ch16.indd 475 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Part II: Designing Flex Applications
476
7. Select Books from the list of available containers.
8. Click OK to add the new pane to the ViewStack.
9. Repeat Steps 5 through 8, and add an instance of the Authors container with a
label of Authors.
FIGURE 16.3
The Insert Pane dialog box
10. Repeat Steps 5 through 8 again, and add an instance of the ShoppingCart
container with a label of Shopping Cart.
11. Click the left arrow button three times to return to the first layer of the
ViewStack. It should be blank.
12. Click the – button to remove the first layer, leaving only the three you added.
13. Run the application. When the application appears, it should display the Books con-
tainer, because it was the first layer declared within the
ViewStack.
Note
The application displays only one layer at this point, because you haven’t added any interactive components to
control navigation.
n
14. Return to Flash Builder, and switch to Source mode.
The generated
ViewStack code looks like this:
22_488959-ch16.indd 47622_488959-ch16.indd 476 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 16: Managing Application Navigation
477
<mx:ViewStack id=”viewstack1” width=”200” height=”200”>
<views:Books label=”Catalog” width=”100%” height=”100%”>
</views:Books>
<views:Authors label=”Authors” width=”100%” height=”100%”>
</views:Authors>
<views:ShoppingCart label=”Shopping Cart” width=”100%”
height=”100%”>
</views:ShoppingCart>
</mx:ViewStack>
The Design mode tool for generating ViewStack code makes a great start but has these issues:
l
The ViewStack is always generated with an initial height and width of 200
pixels each. You can change the
ViewStack dimensions in Design mode by dragging
the
ViewStack handles, or in the Properties view. And of course, you can always change
or remove the dimensions completely in Source mode.
l
Design mode has no mechanism for visually reordering a ViewStack container’s
layers. If you want to change the order of the views, you must do so in Source mode by
changing the order of the child containers.
l
All containers’ MXML declarations are generated with tag sets, such as:
<views:Books label=”Catalog” width=”100%” height=”100%”>
</views:Books>
Particularly when using custom components, the MXML code would be more efficient
with empty tag syntax:
<views:Books label=”Catalog” width=”100%” height=”100%”/>
This is purely a matter of code aesthetics though, and it doesn’t have any negative effect
on application functionality or performance.
After generating a
ViewStack in Design mode, revise the generated code as needed in Source mode.
Working with navigator containers in ActionScript
When a navigator container is initially constructed and displayed, it displays the currently active
view (by default, the first view declared in the stack). You can change the active view at runtime
with ActionScript commands that reference one of these
ViewStack properties:
l
selectedIndex:int. The numeric index position of the active container within the stack.
l
selectedChild:Container. The object reference of the active container within the stack.
Using selectedIndex
The selectedIndex property returns the index position of the currently active container, as
determined by the order of the
ViewStack container’s display list. When declaring a ViewStack
in MXML, the display list order and the order of MXML declaration are the same.
As with all index operations in ActionScript, indexing starts at 0. So the first container with the
view stack is at position 0, the second at position 1, and so on.
22_488959-ch16.indd 47722_488959-ch16.indd 477 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Part II: Designing Flex Applications
478
To change the currently selected view by index, set the stack’s selectedIndex property to the
numeric index of the container you want to activate. This code makes the
viewstack1 contain-
er’s second layer visible and active:
<s:Button label=”Authors” click=”viewstack1.selectedIndex=1”/>
Because indexing always begins at 0, this Button would enable the user to navigate to the first
layer of a stack:
<s:Button label=”First Layer” click=”viewstack1.selectedIndex=0”/>
Using numChildren
The numChildren property returns the total number of layers in the stack as an int value.
Taking into account the 0-based indexing offset, clicking this
Button would result in navigating
to the last layer of a stack:
<s:Button label=”Last Layer”
click=”viewstack1.selectedIndex=viewstack1.numChildren-1”/>
Navigating forward and backward through view stack layers
You can navigate forward and backward through layers of a view stack by incrementing or decre-
menting the stack’s
selectedIndex property. This Button would enable the user to move to
the previous layer of a stack:
<s:Button label=”Authors” click=”viewstack1.selectedIndex ”/>
Note
The selectedIndex property of a ViewStack can’t be set to less than 0. If the Button control in the pre-
ceding code is clicked when the
ViewStack container’s selectedIndex is already set to 0, the command is
ignored and there is no runtime error.
n
You also can navigate forward through a stack, but if you set the selectedIndex to a value
greater than the stack’s highest available index, an “array out of bounds” error results. You can pre-
vent this by wrapping the code to navigate forward in a conditional clause that checks to be sure
that the last container in the stack isn’t already active:
private function navForward():void
{
if (viewstack1.selectedIndex != viewstack1.numChildren-1)
{
viewstack1.selectedIndex++;
}
}
Alternatively, you can set the Button control’s enabled property to false when selected
Index
indicates that a forward or backward navigation either wouldn’t work or would result in a
runtime error. Binding expressions that evaluate
selectedIndex and return a Boolean value
to the
enabled property can handle this task dynamically.
22_488959-ch16.indd 47822_488959-ch16.indd 478 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Chapter 16: Managing Application Navigation
479
The following Button control that navigates forward is enabled only when the ViewStack con-
tainer’s
selectedIndex isn’t already set to the highest index:
<s:Button label=”Next >>”
click=”viewstack1.selectedIndex++”
enabled=”{viewstack1.selectedIndex != viewstack1.numChildren-1}”/>
Managing binding issues
In the preceding code example, the binding expression used in the enabled property might be
executed upon application startup before the
ViewStack container’s numChidren property can
be correctly evaluated. If this happens, you might see that the
Button controls are incorrectly
enabled and disabled upon application startup.
To fix this sort of timing issue, call the
ViewStack container’s executeBindings() method
with a recursive argument of
true to reevaluate all its dependent binding expressions. If you call
this method upon the
ViewStack container’s creationComplete event, it evaluates any
bound property values such as
numChildren again and the Button control’s enabled states
will be correctly calculated:
<mx:ViewStack id=”viewstack1” width=”400” height=”200”
creationComplete=”executeBindings(true)”>
<views:Books label=”Catalog” width=”100%” height=”100%”/>
<views:Authors label=”Authors” width=”100%” height=”100%”/>
<views:ShoppingCart label=”Shopping Cart” width=”100%”
height=”100%”/>
</mx:ViewStack>
The application in Listing 16.2 implements forward and backward navigation with a ViewStack
and
Button controls. Each Button control has its enabled property set through a binding
expression, and the
ViewStack re-executes its bindings upon its creationComplete event.
LISTING 16.2
An application using forward and backward navigation
<?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”
xmlns:views=”views.*”>
<s:layout>
<s:VerticalLayout horizontalAlign=”left”
paddingTop=”20” paddingLeft=”20”/>
</s:layout>
<fx:Style source=”assets/styles.css”/>
<views:Header/>
<s:HGroup>
continued
22_488959-ch16.indd 47922_488959-ch16.indd 479 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
Part II: Designing Flex Applications
480
LISTING 16.2
(continued)
<s:Button label=”<< Previous”
click=”viewstack1.selectedIndex ”
enabled=”{viewstack1.selectedIndex != 0}”/>
<s:Button label=”Next >>”
click=”viewstack1.selectedIndex++”
enabled=”{viewstack1.selectedIndex !=
viewstack1.numChildren-1}”/>
</s:HGroup>
<mx:ViewStack id=”viewstack1” width=”400” height=”200”
creationComplete=”executeBindings(true)”>
<views:Books label=”Catalog” width=”100%” height=”100%”/>
<views:Authors label=”Authors” width=”100%” height=”100%”/>
<views:ShoppingCart label=”Shopping Cart” width=”100%” height=”100%”/>
</mx:ViewStack>
</s:Application>
On the Web
The code in Listing 16.2 is available in the Web site files as BookStoreIndexNavigation.mxml in the
chapter16 project.
n
Figure 16.4 shows the resulting application, with Previous and Next buttons to handle backward
and forward navigation.
Using selectedChild
The ViewStack container’s selectedChild property accesses the stack’s currently visible view
by its object reference. To use this property, each of the stack’s nested containers should be
assigned a unique
id:
<mx:ViewStack id=”viewstack1”>
<views:Books id=”booksView”/>
<views:Authors id=”authorsView”/>
<views:ShoppingCart id=”cartView”/>
</mx:ViewStack>
To select an active view by the container’s unique id, set the ViewStack container’s
selectedChild:
<s:Button label=”Shoppping Cart”
click=”viewstack1.selectedChild=cartView”/>
Note
Notice that there are no quotes around the cartView container’s id when it’s assigned in this way. You’re
accessing the
id as a variable or component instance id, not a String value.
n
22_488959-ch16.indd 48022_488959-ch16.indd 480 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... describe each option and provide examples of how you can use these classes and controls On the Web To use the sample code for this chapter, import the chapter17.zip Flex project archive from the Web site files into your Flash Builder workspace n 503 IN THIS CHAPTER Understanding pop-up windows Using the Alert class Using the PopUpMenuButton control Using the PopUpButton control Creating and displaying custom... and notify you of user selections with both an itemClick and change event The PopupMenuButton control differs from the other menu controls, in that it displays only a single-level menu and notifies you of a user selection with its change event In this section I describe the details of using the Menu and MenuBar controls The PopupMenuButton control is described in Chapter 17 49 1 Part II: Designing Flex. .. xmlns:s=”library://ns.adobe.com /flex/ spark” xmlns:mx=”library://ns.adobe.com /flex/ mx” xmlns:views=”views.*”> continued 48 7 Part II: Designing Flex Applications LISTING 16.5 (continued) ... the appearance of the ButtonBar component and its child button objects by creating custom skins both for the navigator container and for its children n Using Menu Controls Flex provides three menu controls that you can use to create styles of navigation interfaces They include the MX Menu, MenuBar, and PopupMenuButton controls Of these three controls, the Menu and MenuBar define their menus with a hierarchical... xmlns:fx=”http://ns.adobe.com/mxml/2009” xmlns:s=”library://ns.adobe.com /flex/ spark” xmlns:mx=”library://ns.adobe.com /flex/ mx”> 48 5 Part II: Designing Flex Applications LISTING 16 .4 (continued) { var buttonURL:String = buttonData.getItemAt(event.newIndex).url; var request:URLRequest... Tip As with all nonvisual objects, instances of XML and XMLList must be declared inside an element in Flex4 applications n You can select any element and attribute names you like in the XML structure, but you should follow these recommendations when using a menu control with a ViewStack: l l 49 2 Each menu item should have a consistently named attribute to serve... Detailed information about retrieving XML and parsing it with E4X is available in Chapters 23 and 24 n Caution If you forget to set the menu control’s labelField to a consistently named attribute or property of the underlying data, the labels of the menu items sometimes present raw XML because the control doesn’t have any instructions for parsing the data n Handling menu events When the user selects... custom event handler can then access the selected XML node’s attributes and use them to execute navigation This event handler function retrieves the node’s view attribute with an array-style expression to change the active view container of the ViewStack: import mx.events.MenuEvent; private function menu_ClickHandler(event:MenuEvent):void { viewstack1.selectedChild = this[event.item.@view]; } 49 3 Part II:... data provider Then present the Menu with its show() method, passing optional xShow and yShow coordinates as arguments This event handler function responds to a mouse event by creating a Menu with a data provider named menuData and the application as the parent window, and then displays it at the mouse event’s stageX and stageY coordinates The application in Listing 16.8 uses a Menu populated with an... uses the same sort of data and generates the same events as the Menu control Unlike the Menu, it’s designed to be placed in a static position in the application and serve as a navigation or functional menu, so it’s typically declared in MXML: 49 5 Part II: Designing Flex Applications The application .
n
14. Return to Flash Builder, and switch to Source mode.
The generated
ViewStack code looks like this:
22 _48 8959-ch16.indd 47 622 _48 8959-ch16.indd 47 6. starting application with a custom Header component
22 _48 8959-ch16.indd 47 422 _48 8959-ch16.indd 47 4 3/5/10 2:30 PM3/5/10 2:30 PM
Please purchase PDF Split-Merge