(十四)Flex4_导航
Flex中实现导航有两种方式可以实现
1.使用状态,在不同事件发生时切换到指定的状态,不同的状态对应不同的视图界面
2.使用导航容器
--------------------------------
导航:实现多页视图的切换显示
1.实现导航基础的ViewStack类
2.NavigationContent类,该类支持在ViewStack中使用基于Spark的容器
3.实现导航时使用ViewStack类的selectedIndex和selectedChild属性
导航容器
重要概念:
容器:ViewStack
组件:NavigationContent (Spark元素)
说明:
任何实现了INavigationContent接口的类都可以作为ViewStack的子元素。
在spark中,NavigationContent实现了INavigationContent并且继承了Sprak Group类
导航容器每次只显示一个子元素,ViewStack通过切换其子元素的可见性实现子元素的呈现
如何切换元素呢?
通过selectedChild和selectedIndex属性控制元素在导航容器中的可见性
[selectedIndex:ViewStack索引从0开始,第一个子元素的索引为0]
[selectedChilde:通过引用子元素的id值,从而指定ViewStack显示哪个元素]
----------------------------
1.主程序设置状态:
<s:states><s:State name="shoppingView"/><s:State name="checkoutView"/></s:states>
<?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" creationComplete="handleCreationComplete(event)" xmlns:views="views.*" xmlns:services="services.*" xmlns:cart="cart.*"><!-- 购物视图、结账视图--><s:states><s:State name="shoppingView"/><s:State name="checkoutView"/></s:states><fx:Declarations><!-- Place non-visual elements (e.g., services, value objects) here --><!-- 将HTTPService获取数据的功能放到两个ActionScript类中进行处理,此处引入即可 --><!-- 提供商品类别服务的组件(不可见组件)--><services:CategoryService id="categoryService"/><!-- 提供具体各种商品服务的组件(不可见组件)--><services:ProductService id="productService"/><!-- 创建购物车实例,将同一个对象传入到shoppingView和checkoutView两个状态下--><cart:ShoppingCart id="shoppingCart"/></fx:Declarations><fx:Script><![CDATA[import events.OrderEvent;import mx.controls.Alert;import mx.events.FlexEvent;import spark.events.IndexChangeEvent;//当系统组件构建完成后,会调用到此方法,在这里向远端发起请求,获取数据//当数据获取成功后,事件监听器会调用指定的方法处理数据private function handleCreationComplete(event:FlexEvent):void {categoryService.send();productService.send();}//查看当前购物车中的商品private function handleViewCartClick( event:MouseEvent ):void {bodyGroup.currentState="cartView";//切换到bodyGroup下的cartView状态}//响应列表的变化,对change事件进行处理protected function list1_changeHandler(event:IndexChangeEvent):void{//当控制条中商品的选中状态改变了,会触发change事件,该方法就会得到执行//传入当前选中商品的catID,然后products集合会根据此id寻找对应的项,并只呈现匹配的哪些项productService.filterCollection(event.target.selectedItem.categoryID);}protected function btnCheckout_clickHandler(event:MouseEvent):void{// 转到结账视图this.currentState = "checkoutView";}protected function FlexGrocer_clickHandler(event:MouseEvent):void{// 转到购物视图this.currentState = "shoppingView";}// 主应用程序的checkoutView组件派发placeOrder自定义事件之后,表示需要完成结账protected function checkout_placeOrderHandler(event:OrderEvent):void{//当用户结账时,弹出提示框描述相关信息Alert.show("Place an order for " +event.order.billingName + " with a total of " + shoppingCart.total,"Order Placed");//清空购物车shoppingCart = new ShoppingCart();//当前状态切换到购物视图状态this.currentState = "shoppingView";//防止ShoppingView组件处于cartView状态,将其切换回State1状态bodyGroup.currentState = "State1";}]]></fx:Script><!-- 控制条布局 --><s:controlBarLayout><s:BasicLayout/></s:controlBarLayout><!-- 控制条 --><s:controlBarContent><s:Button y="10" label="Checkout" id="btnCheckout" right="10" click="btnCheckout_clickHandler(event)"/><s:Button y="10" label="View Cart" id="btnCartView" right="90" click="handleViewCartClick( event )"/><s:Button label="Flex Grocer" x="5" y="5" click="FlexGrocer_clickHandler(event)"/><!-- 从categoryService中获取商品种类信息 ,使用指定的项目呈现器NavigationItem显示内容--><s:List left="200" height="52" dataProvider="{categoryService.categories}"itemRenderer="components.NavigationItem"change="list1_changeHandler(event)"includeIn="shoppingView"><s:layout><s:HorizontalLayout/></s:layout></s:List></s:controlBarContent><!-- 实例化商品组件(该组件被单独抽取出来,在主应用程序中实例化) --><!-- 从productService中获取商品 --><views:ShoppingView id="bodyGroup" width="100%" height="100%" groceryInventory="{productService.products}"includeIn="shoppingView"shoppingCart="{shoppingCart}"/><!-- 结账视图--><views:CheckOutView x="0" y="0" width="100%" height="100%"includeIn="checkoutView"shoppingCart="{shoppingCart}"placeOrder="checkout_placeOrderHandler(event)"/><!-- 版权说明 --><s:Label text="(c) 2009, FlexGrocer" right="10" bottom="10"/></s:Application>
<?xml version="1.0" encoding="utf-8"?><s:Group 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:valueObjects="valueObjects.*" xmlns:checkout="views.views.checkout.*"><s:layout><s:VerticalLayout/></s:layout><fx:Declarations><!-- 将非可视元素(例如服务、值对象)放在此处 --><!-- 创建OrderInfo数据模型对象--><valueObjects:OrderInfo id="orderInfo"/></fx:Declarations><!-- 声明自定义OrderEvent事件(当completeOrder的时候会发生此事件)--><fx:Metadata>[Event(name="placeOrder", type="events.OrderEvent")]</fx:Metadata><fx:Script><![CDATA[import cart.ShoppingCart;import events.OrderEvent;[Bindable]public var shoppingCart:ShoppingCart;//继续到下一个页面protected function proceedHandler(event:Event):void{vs.selectedIndex += 1;}//返回编辑信息,即回到初始页面protected function editInformationHandler(event:Event):void{vs.selectedIndex = 0;}//完成订单,结账protected function completeOrderHandler(event:Event):void{// 为下一个订单重置导航vs.selectedIndex = 0;// 在自定义事件对象中设置orderInfo对象并派发this.dispatchEvent(new OrderEvent('placeOrder',orderInfo));// 清除订单对象,为下一次做准备orderInfo = new OrderInfo();}]]></fx:Script><!-- 利用ViewStack结合NavigationContent实现导航--><mx:ViewStack id="vs" width="100%" height="100%"><!-- page 1 可以进入下一页--><checkout:CustomerInfo orderInfo="{orderInfo}" width="100%" height="100%" proceed="proceedHandler(event)"/><!-- page 2 可以进入下一页--><checkout:CreditCardInfo orderInfo="{orderInfo}" width="100%" height="100%" proceed="proceedHandler(event)"/><!-- page 3 可以返回第一页重新编辑信息,也可以结账完成订单--><checkout:Review orderInfo="{orderInfo}" width="100%" height="100%" shoppingCart="{shoppingCart}" editInformation="editInformationHandler(event)" completeOrder="completeOrderHandler(event)"/></mx:ViewStack></s:Group>
package events {import flash.events.Event;import valueObjects.OrderInfo;public class OrderEvent extends Event {public var order:OrderInfo;//通过构造函数初始化自定义事件对象//在事件对象中设置订单对象,事件监听器可以从event中取出该订单对象,从而获取到订单的详细信息public function OrderEvent(type:String, order:OrderInfo ) {this.order = order;super(type);}override public function clone():Event {return new OrderEvent( type, order );}}}
<?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"><s:layout><s:HorizontalLayout/></s:layout><fx:Declarations><!-- Place non-visual elements (e.g., services, value objects) here --></fx:Declarations><fx:Metadata>[Event(name="proceed", type="flash.events.Event")]</fx:Metadata><fx:Script><![CDATA[import valueObjects.OrderInfo;[Bindable]public var orderInfo:OrderInfo;private function handleProceed( event:Event ):void {dispatchEvent( new Event( 'proceed' ) );}]]></fx:Script><s:Label text="Checkout Page 1 of 3"/><mx:Form><mx:FormHeading label="Customer Information"/><mx:FormItem label="Customer Name"><!-- "@"符表示将会把输入的数据设置到对象的属性中,传说中的双向数据绑定? --><s:TextInput text="@{orderInfo.billingName}"/></mx:FormItem><mx:FormItem label="Address"><s:TextInput text="@{orderInfo.billingAddress}"/></mx:FormItem><mx:FormItem label="City"><s:TextInput text="@{orderInfo.billingCity}"/></mx:FormItem><mx:FormItem label="State"><s:TextInput text="@{orderInfo.billingState}"/></mx:FormItem><mx:FormItem label="Zip"><s:TextInput text="@{orderInfo.billingZip}"/></mx:FormItem><mx:FormItem label="Delivery Date"><mx:DateField selectedDate="@{orderInfo.deliveryDate}"/></mx:FormItem><mx:FormItem><s:Button label="Proceed" click="handleProceed( event )"/></mx:FormItem></mx:Form></s:NavigatorContent>
<?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"><s:layout><s:VerticalLayout/></s:layout><fx:Declarations><!-- Place non-visual elements (e.g., services, value objects) here --></fx:Declarations><fx:Metadata>[Event(name="proceed", type="flash.events.Event")]</fx:Metadata><fx:Script><![CDATA[import mx.collections.IList;import spark.events.IndexChangeEvent;import valueObjects.OrderInfo;[Bindable]public var orderInfo:OrderInfo;private function handleProceed( event:Event ):void {dispatchEvent( new Event( 'proceed' ) );}]]></fx:Script><s:Label text="Checkout Page 2 of 3"/> <mx:Form><mx:FormHeading label="Billing Information"/><mx:FormItem label="Credit Card Type"><s:DropDownList selectedItem="@{orderInfo.cardType}" requireSelection="true"><s:dataProvider><s:ArrayList><fx:String>American Express</fx:String><fx:String>Diners Club</fx:String><fx:String>Discover</fx:String><fx:String>MasterCard</fx:String><fx:String>Visa</fx:String></s:ArrayList></s:dataProvider></s:DropDownList></mx:FormItem><mx:FormItem label="Card Number"><s:TextInput text="@{orderInfo.cardNumber}"/></mx:FormItem><mx:FormItem label="Expiration" direction="horizontal"><s:DropDownList selectedItem="@{orderInfo.cardExpirationMonth}" requireSelection="true"><s:dataProvider><s:ArrayList><fx:String>January</fx:String><fx:String>February</fx:String><fx:String>March</fx:String><fx:String>April</fx:String><fx:String>May</fx:String><fx:String>June</fx:String><fx:String>July</fx:String><fx:String>August</fx:String><fx:String>September</fx:String><fx:String>October</fx:String><fx:String>November</fx:String><fx:String>December</fx:String></s:ArrayList></s:dataProvider></s:DropDownList><s:DropDownList selectedItem="@{orderInfo.cardExpirationYear}" requireSelection="true"><s:dataProvider><s:ArrayList><fx:String>2010</fx:String><fx:String>2011</fx:String><fx:String>2012</fx:String><fx:String>2013</fx:String><fx:String>2014</fx:String><fx:String>2015</fx:String></s:ArrayList></s:dataProvider></s:DropDownList></mx:FormItem><mx:FormItem><s:Button label="Proceed" click="handleProceed( event )"/></mx:FormItem></mx:Form></s:NavigatorContent>
<?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" xmlns:components="components.*"><s:layout><s:VerticalLayout/></s:layout><fx:Declarations><!-- Place non-visual elements (e.g., services, value objects) here --></fx:Declarations><fx:Metadata>[Event(name="editInformation", type="flash.events.Event")][Event(name="completeOrder", type="flash.events.Event")]</fx:Metadata><fx:Script><![CDATA[import cart.ShoppingCart;import cart.ShoppingCartItem;import events.OrderEvent;import events.ProductEvent;import valueObjects.OrderInfo;import valueObjects.Product;[Bindable]public var shoppingCart:ShoppingCart;[Bindable]public var orderInfo:OrderInfo;private function handleComplete( event:Event ):void {dispatchEvent( new Event( 'completeOrder' ) ); }private function handleEdit( event:Event ):void {dispatchEvent( new Event( 'editInformation' ) );}private function removeProductHandler(event:ProductEvent):void {var sci:ShoppingCartItem = new ShoppingCartItem( event.product );shoppingCart.removeItem( sci );}]]></fx:Script><s:Label text="Checkout Page 3 of 3"/><s:HGroup width="100%" height="90%"><!-- 显示用户前面输入的个人基本信息 --><mx:Form><mx:FormHeading label="Review and Checkout"/><mx:FormItem label="Name"><s:Label text="{orderInfo.billingName}"/></mx:FormItem><mx:FormItem label="Address"><s:Label text="{orderInfo.billingAddress}"/><s:Label text="{orderInfo.billingCity}, {orderInfo.billingState} {orderInfo.billingZip}"/></mx:FormItem><mx:FormItem label="Card Type"><s:Label text="{orderInfo.cardType}"/></mx:FormItem><mx:FormItem label="Delivery Date"><s:Label text="{orderInfo.deliveryDate}"/></mx:FormItem><mx:FormItem><s:Button label="Complete Order" click="handleComplete( event )"/><s:Button label="Edit Information" click="handleEdit( event )"/></mx:FormItem></mx:Form><!--将购物车的详细信息进行显示--><s:VGroup width="100%" height="100%"><components:CartGrid id="dgCart" width="100%" height="100%" dataProvider="{shoppingCart.items}" removeProduct="removeProductHandler( event )"/><s:Label text="Total {shoppingCart.total}"/></s:VGroup></s:HGroup></s:NavigatorContent>