论坛风格切换切换到宽版
  • 17923阅读
  • 3回复

flex4 states 状态 页面切换 详解 教程 [复制链接]

上一主题 下一主题
 

发帖
1077
只看楼主 倒序阅读 使用道具 楼主  发表于: 2010-07-28
在flex4 里面 使用了更方便 states 来组织代码.  
flex 中的states 可以理解为 一个组件的一个状态.  例如一个按钮可以有不同的状态, 按下,弹起,默认 等.
如果是针对一个布局的组件或一个应用, 则一个状态可以理解为一个页面.  例如在传统的html代码中,一个url就是一个页面或一个状态,   在flex中 一个 application 的不同状态 实际上就等于不同页面.

在flashbuilder4中,非常方便的可视化操作状态.

教程 http://www.adobe.com/devnet/flex/videotraining/exercises/ex4_07.html
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7fb4.html

这里举个例子说明
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7ff1.html
在代码中定义2个状态"default" 和 "NewButton"

  1. <s:states>
  2.         <!-- Define the new view states. -->
  3.         <s:State name="default"/>
  4.         <s:State name="NewButton"/>
  5. </s:states>  


通过Flashbuilder的右上角的状态面板 可以方便新建一个状态 和 设置默认的状态  这里默认状态设置为 default
即在 application 里面 写上currentState="default"

  1. <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"     minWidth="1024" minHeight="768" currentState="default">


使用includeIn 和 excludeFrom 可以让组件包含在某个状态中.
该例子中的组件 属于某个状态 就可以 用 includeIn="default"  属性 表明该组件是default状态
不属于某个状态 可以用 excludeFrom="NewButton"  属性 表明 该组件不属于NewButton状态.
includeIn 和 excludeFrom 是互斥的,不能同时用于一个组件上

状态切换 currentState='loginState'
通过在事件中使用 currentState='loginState' 切换状态
例如在按钮的点击事件中 切换到portalState 状态

  1. <s:Button x="10" y="90" label="Login" click="{currentState='portalState'}"/>


效果演示


  1. <?xml version="1.0"?>
  2. <!-- states\StatesSimple.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark">
  6.     <s:states>
  7.         <!-- Define the new view states. -->
  8.         <s:State name="default"/>
  9.         <s:State name="NewButton"/>
  10.     </s:states>    
  11.     <s:VGroup id="g1">
  12.         <s:HGroup>
  13.             <!-- Disable Button in the NewButton view state. -->
  14.             <s:Button id="b1" label="Click Me"
  15.                 enabled.NewButton="false"/>
  16.             <!-- Add a new child control to the VBox. -->
  17.             <s:Button id="b2" label="New Button"
  18.                 includeIn="NewButton"/>
  19.         </s:HGroup>
  20.         <!-- Define Button control to switch to NewButton view state. -->
  21.         <s:Button label="Change to NewButton state"
  22.             click="currentState='NewButton';"/>            
  23.         <!-- Define Button control to switch to default view state. -->
  24.         <s:Button label="Change to default view state"
  25.             click="currentState='default';"/>
  26.     </s:VGroup>    
  27. </s:Application>


更复杂的状态应用 请看 http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7ffa.html

通过组件标签的点语法 可以改变不同状态下属性的值,例如如下代码 x.State2="10"

则为在状态State2时 button 文字由Default State改为New State, 并且 x的坐标改为10

  1. <s:Button label="Default State" label.State2="New State" x.State2="10"/>

通过@Clear() 可以清空属性在某个状态下的值.

  1. <s:Button color="0xFF0000" color.State1="@Clear()"/>


例如 1 不同状态下显示不同的组件


  1. <?xml version="1.0"?>
  2. <!-- states\StatesSimpleIncExc.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark">
  6.     <s:layout>
  7.         <s:VerticalLayout/>
  8.     </s:layout>
  9.     <s:states>
  10.         <s:State name="default"/>
  11.         <s:State name="addCheckBox"/>
  12.         <s:State name="addTextInput"/>
  13.         <s:State name="addCheckBoxandButton"/>
  14.     </s:states>
  15.     
  16.     <s:HGroup >
  17.         <!-- //该checkbox在两个状态中addCheckBox,addCheckBoxandButton中. -->
  18.         <s:CheckBox id="myCB" label="Checkbox"
  19.            includeIn="addCheckBox, addCheckBoxandButton"/>
  20.     
  21.         <!-- Included in the addTextInput view state. -->
  22.         <s:TextInput id="myTI"
  23.            includeIn="addTextInput"/>    
  24.         <!-- Included in the addCheckBoxandButton view state. -->
  25.         <s:Button id="myB"
  26.            includeIn="addCheckBoxandButton"/>
  27.         
  28.         <!-- Exclude from addTextInput view state. -->
  29.         <s:TextArea text="Exclude from addTextInput"
  30.             excludeFrom="addTextInput"/>        
  31.     </s:HGroup>
  32.     <s:HGroup>
  33.         <s:Button label="Add CheckBox"
  34.             click="currentState='addCheckBox'"/>
  35.         <s:Button label="Show Textinput Only"
  36.             click="currentState='addTextInput'"/>    
  37.         <s:Button label="Add CheckBox and Button"
  38.             click="currentState='addCheckBoxandButton'"/>
  39.         <s:Button label="Default"
  40.             click="currentState='default'"/>
  41.     </s:HGroup>
  42. </s:Application>


例如 2 使用 <fx:Reparent target="targetComp" includeIn="stateName"> 使一个组件在不同的状态下 切换
注意fx:Reparent 只能改变组件属于一个父级的容器中, 不能从属于多个父容器.



  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- states\NewStatesReparent.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark">
  6.     <s:layout>
  7.         <s:VerticalLayout/>
  8.     </s:layout>
  9.     <s:states>
  10.         <s:State name="Parent1"/>
  11.         <s:State name="Parent2"/>
  12.     </s:states>
  13.     
  14.     <s:HGroup>
  15.         <s:Panel id="Panel1"
  16.             height="100" width="100"
  17.             title="Panel 1">
  18.             <s:Button id="setCB" includeIn="Parent1"/>
  19.         </s:Panel>
  20.         <s:Panel id="Panel2"
  21.             height="100" width="100"
  22.             title="Panel 2">
  23.             <fx:Reparent target="setCB" includeIn="Parent2"/>
  24.         </s:Panel>    
  25.     </s:HGroup>
  26.     <s:HGroup>
  27.         <s:Button label="Parent 1"
  28.             click="currentState='Parent1'"
  29.             enabled.Parent1="false"/>
  30.         <s:Button label="Parent 2"
  31.             click="currentState='Parent2'"
  32.             enabled.Parent2="false"/>
  33.     </s:HGroup>
  34. </s:Application>


在状态改变的过程中, 通过itemCreationPolicy  属性来控制何时 创建组件的实例
itemCreationPolicy  有2个值:
deferred  状态改变时组件才被创建并添加,改值为默认值.
immediate :在程序application 开始运行后 组件就被创建.

当状态改变后,组件从一个状态中移除或不显示,即使永远也不在显示,该组件还是存在于程序中.
如果组件在程序运行时就创建,那么什么时候都可以使用它,否则你只有在第一次状态更改时,创建该组件后才可以.

组件创建的过程请看creation policy ,和性能相关的部分章节 Improving startup performance.

使用 itemDestructionPolicy 可以控制组件的缓存, 值为 " never" (默认值) 和 "auto"
一般来讲缓存可以提高组件性能,使用"never"为永远不清空缓存. 当然你也可以在使用"auto"值,当组件改变状态后并不在显示或用到时将清空缓存. 例如下面如果组件不属于newTextInput状态 将会清除缓存

  1. <s:TextInput includeIn="newTextInput" itemDestructionPolicy="auto"/>


state group 状态组
通过设置页面状态组,可以使用includeIn 等把组件属于一个状态组中,更灵活组织页面状态.

  1. <s:states>
  2.         <s:State name="default"/>
  3.         <s:State name="addCheckBox" stateGroups="Group1"/>
  4.         <s:State name="addTextInput"/>
  5.         <s:State name="addCheckBoxandButton" stateGroups="Group1"/>
  6.     </s:states>
  7. <s:HGroup>
  8.         <!-- Included in the addCheckBox and addCheckBoxandButton view states. -->
  9.         <s:CheckBox id="myCB" label="Checkbox"
  10.             includeIn="Group1"/>
  11.     
  12.        <!-- Included in the addTextInput view state. -->
  13.        <s:TextInput id="myTI"
  14.             includeIn="addTextInput"/>    
  15.         <!-- Included in the addCheckBoxandButton view state. -->
  16.         <s:Button id="myB"
  17.            includeIn="addCheckBoxandButton"/>
  18.         
  19.         <!-- Exclude from addTextInput view state. -->
  20.         <s:TextArea text="Exclude from addTextInput"
  21.            excludeFrom="addTextInput"/>            
  22.     </s:HGroup>


范例:三个面板换位


  1. <?xml version="1.0"?>
  2. <!-- states/ThreePanelGroups.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark" width="400">
  6.     <!-- Define the two view states, in addition to the default state.-->
  7.     <s:states>
  8.         <s:State name="default" stateGroups="grpDefaultOne, grpDefaultTwo"/>
  9.         <s:State name="One" stateGroups="grpDefaultOne, grpOneTwo "/>
  10.         <s:State name="Two" stateGroups="grpDefaultTwo, grpDefaultTwo, grpOneTwo"/>
  11.     </s:states>
  12.     <!-- Define the Group container holding the three Panel containers.-->
  13.     <s:Group width="100%" height="100%">
  14.         <s:Panel id="p1" title="One"
  15.                 x.grpDefaultTwo="0" y.grpDefaultTwo="0"
  16.                 x.One="110" y.One="0"
  17.                 width.grpDefaultTwo="100" height.grpDefaultTwo="100"
  18.                 width.One="200" height.One="210"
  19.                 click="currentState='One'">
  20.             <s:Label fontSize="24" text="One"/>
  21.         </s:Panel>
  22.         
  23.         <s:Panel id="p2" title="Two"
  24.                 x="0" y="110"
  25.                 x.One="0" y.One="0"
  26.                 x.Two="110" y.Two="0"
  27.                 width.grpDefaultOne="100" height.grpDefaultOne="100"
  28.                 width.Two="200" height.Two="210"
  29.                 click="currentState='Two'">
  30.             <s:Label fontSize="24" text="Two"/>
  31.         </s:Panel>
  32.         
  33.         <s:Panel id="p3" title="Three"
  34.                 x="110" y="0"
  35.                 x.grpOneTwo="0" y.grpOneTwo="110"
  36.                 width="200" height="210"
  37.                 width.grpOneTwo="100" height.grpOneTwo="100"
  38.                 click="currentState='default'">
  39.             <s:Label fontSize="24" text="Three"/>
  40.         </s:Panel>
  41.     </s:Group>
  42. </s:Application>

发帖
1077
只看该作者 沙发  发表于: 2010-10-15
view state events 状态触发的事件
与状态有关的事件
http://www.cnblogs.com/orchid/archive/2009/07/18/1526310.html
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7ffa.html

下面接收4个与状态有关的事件:

    * enterState:进入一个新状态后触发,触发者是state object和组件。
    * exitState:一个状态将要离开时触发,触发者是state object和组件。
    * currentStateChanging:在状态即将改变时触发。它被一个currentState属性值改变的组件触发。你可以利用这个事件向服务器请求即将被新状态用到的数据。
    * currentStateChange:在一个状态已经完全改变了后触发。你可以利用这个事件向服务器发回一个数据,指明用户当前的状态。

看个实例好了!

  1. <?xml version="1.0"?>
  2. <!-- states\StatesSimpleEvent.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark"
  6.     height="450">
  7.     <s:states>
  8.         <!-- Define the new view states. -->
  9.         <s:State name="default"
  10.             enterState="MyEnterTA.text = 'Enter state: default';"
  11.             exitState="MyExitTA.text = 'Exit state: default';"/>
  12.         <s:State name="NewButton"
  13.             enterState="MyEnterTA.text = 'Enter state: NewButton';"
  14.             exitState="MyExitTA.text = 'Exit state: NewButton';"/>
  15.     </s:states>    
  16.     <s:VGroup id="g1">
  17.         <s:HGroup>
  18.             <s:Button id="b1" label="Click Me"
  19.                 enabled.NewButton="false"/>
  20.             <s:Button id="b2" label="New Button"
  21.                 includeIn="NewButton"/>
  22.         </s:HGroup>
  23.         <s:Button label="Change to NewButton state"
  24.             click="currentState='NewButton';"/>            
  25.         <s:Button label="Change to default view state"
  26.             click="currentState='default';"/>
  27.         <s:TextArea id="MyEnterTA"/>
  28.         <s:TextArea id="MyExitTA"/>
  29.         
  30.     </s:VGroup>    
  31. </s:Application>



用浏览器切换状态
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7fea.html

Flex browser manager能够让用户通过浏览器的前进后退按钮来导航应用。因为这个browser manager能够对状态的切换进行跟踪。    

以前说过,每个状态是个新的界面,而不是一个新的页面。但是用浏览器也能实现不同状态之间的切换。如何做到呢?先看看背景知识。
BrowserManager:一个 Singleton 管理器,用于充当浏览器和应用程序之间的代理。使用它可以访问浏览器地址栏中的 URL,这与访问 JavaScript 中的 document.location 属性类似。它有一个getInstance() 方法,返回的是一个IBrowserManager类的实例。
IBrowserManager:由 BrowserManager 的共享实例实现的接口。init()方法:初始化 BrowserManager。fragment属性:当前 URL 显示在浏览器地址栏中时,“#”之后的部分。
看个实例

  1. <?xmlversion="1.0"?>
  2. <!-- states\StatesBrowserManager.mxml-->
  3. <s:Applicationxmlns:fx="http://ns.adobe.com/mxml/2009"
  4. xmlns:mx="library://ns.adobe.com/flex/halo"
  5. xmlns:s="library://ns.adobe.com/flex/spark"
  6. creationComplete="initApp();">
  7. <fx:Script>
  8. <![CDATA[
  9. importmx.managers.BrowserManager;
  10. import mx.managers.IBrowserManager;
  11. importmx.events.BrowserChangeEvent;
  12. import mx.utils.URLUtil;
  13. // The searchstring value.
  14. [Bindable]
  15. public var searchString:String;
  16. // 一个BrowserManager 类的实例.
  17. private varbrowserManager:IBrowserManager;
  18. //在应用创建完成时初始化 BrowserManager.
  19. publicfunction initApp():void {
  20. browserManager =BrowserManager.getInstance();
  21. browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE,parseURL);
  22. browserManager.init("", "Browser Manager for ViewStates");
  23. updateURL('default');
  24. }
  25. //当用户按前进后退按钮时触发事件,事件处理器从URL里接到状态的值,从而。用他
  26. //设定当前状态。
  27. private varstateFromURL:String;
  28. private function parseURL(e:Event):void {
  29. varo:Object = URLUtil.stringToObject(browserManager.fragment);
  30. stateFromURL =o.state;
  31. currentState=stateFromURL;
  32. }
  33. // 状态改变时改变地址。
  34. private functionupdateURL(myCurrentState:String):void {
  35. var s:String = "state=" +myCurrentState;
  36. browserManager.setFragment(s);
  37. }
  38. //当按下go按钮时执行该方法。
  39. // 它会改变状态以及调用updateURL()方法来改变URL。
  40. public functiondoSearch():void {
  41. currentState ="results";
  42. updateURL('results');
  43. searchString =searchInput.text;
  44. }
  45. // 点击reset按钮时执行该方法,该方法是状态改到默认值,。并且改变URL
  46. publicfunction reset():void {
  47. currentState = '';
  48. searchInput.text ="";
  49. searchString ="";
  50. updateURL('default');
  51. }
  52. ]]>
  53. </fx:Script>
  54. <s:states>
  55. <!--The state for displaying the search results -->
  56. <s:Statename="default"/>
  57. <s:Statename="results"/>
  58. </s:states>
  59. <!-- In the default state, justshow a panel
  60. with a search text input and button. -->
  61. <s:Panelid="panel1"
  62. title="Search"title.results="Results"
  63. resizeEffect="Resize"
  64. width="10%"height="10%"
  65. width.results="100%"height.results="100%">
  66. <s:layout>
  67. <s:VerticalLayout/>
  68. </s:layout>
  69. <s:SkinnableContainerid="searchFields"defaultButton="{b}">
  70. <s:layout>
  71. <s:HorizontalLayout/>
  72. </s:layout>
  73. <s:TextInputid="searchInput"/>
  74. <s:Buttonid="b"
  75. label="Go"
  76. click="doSearch();"/>
  77. <s:ButtonincludeIn="results"
  78. label="Reset"
  79. click="reset();"/>
  80. </s:SkinnableContainer>
  81. <s:SimpleTextincludeIn="results"
  82. text="Search results for{searchString}"/>
  83. </s:Panel>
  84. </s:Application>


有点长哦!
在这个实例中,当用户改变状态时,updateURL()就会将相应的地址写到浏览器的地址栏,当按浏览器的前进或者后退按钮时,parseURL()方法会从URL中获得当前状态值,并且改变状态。

发帖
1077
只看该作者 板凳  发表于: 2011-02-23
自定义组件中的定义状态
http://help.adobe.com/zh_CN/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7ff2.html

首先在自定义组件中定义自己的状态 文件为LoginComponent.mxml




  1. <?xml version="1.0"?>
  2. <!-- states\myComponents\LoginComponent.mxml -->
  3. <!-- Set title of the Panel container based on the view state.-->
  4. <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
  5.     xmlns:mx="library://ns.adobe.com/flex/mx"
  6.     xmlns:s="library://ns.adobe.com/flex/spark"
  7.     title="Login" title.Register="Register">
  8.         
  9.     <!-- The states property defines the view states.-->
  10.     <s:states>
  11.         <s:State name="Login"/>    
  12.         <s:State name="Register"/>
  13.     </s:states>
  14.     <mx:Form id="loginForm">
  15.         <mx:FormItem label="Username:">
  16.             <s:TextInput/>
  17.         </mx:FormItem>
  18.         <mx:FormItem label="Password:">
  19.             <s:TextInput/>
  20.         </mx:FormItem>
  21.         <!-- Add a TextInput control to the form for the Register view state. -->          
  22.         <mx:FormItem id="confirm" label="Confirm:" includeIn="Register">
  23.             <s:TextInput/>
  24.         </mx:FormItem>            
  25.         <mx:FormItem direction="horizontal">            
  26.             <!-- Use the LinkButton to change to the Register view state.-->                  
  27.             <!-- Exclude the LinkButton from the Register view state.-->                  
  28.             <mx:LinkButton id="registerLink"
  29.                 includeIn="Login"
  30.                 label="Need to Register?"
  31.                 click="currentState='Register'"/>
  32.             <!-- Add a LinkButton to the form for the Register view state. -->          
  33.             <mx:LinkButton label="Return to Login"
  34.                 includeIn="Register"
  35.                 click="currentState=''"/>
  36.             <mx:Spacer width="100%" id="spacer1"/>
  37.             <!-- Set label of the control based on the view state.-->
  38.             <s:Button id="loginButton"
  39.                 label="Login" label.Register="Register" />
  40.         </mx:FormItem>            
  41.     </mx:Form>
  42. </s:Panel>


然后在主程序中使用该组件
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- states\LoginMain.mxml -->
  3. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  4.     xmlns:mx="library://ns.adobe.com/flex/mx"
  5.     xmlns:s="library://ns.adobe.com/flex/spark"
  6.     xmlns:MyComp="myComponents.*">
  7.     <s:layout>
  8.         <s:VerticalLayout/>
  9.     </s:layout>
  10.     <s:Label text="Login or Register"
  11.         fontSize="14" fontWeight="bold"/>
  12.     <MyComp:LoginComponent currentState="Login"/> //使用该组件
  13. </s:Application>


发帖
1077
只看该作者 地板  发表于: 2011-05-23
下一讲 :  切换页面效果  通过 transitions  实现切换状态state时 过渡效果  

http://www.fbair.net/bbs/read.php?tid=238
快速回复
限100 字节
批量上传需要先选择文件,再选择上传
 
上一个 下一个