flex4里的state
什么是状态(States)?在很多富互联网应用,网页外观的改变基于用户的行为。一个状态就定义了组件的一种表现样式。要想使用状态,你应该首先定义一个默认的状态,然后在此基础上重写或者更改,这样就形成了一系列的其他样式。你可以添加、移除某些子元素,更改CSS或者属性的值,更改触发的事件。这些如何做到,我们会一一介绍。 下面我们先通过一个例子大概看一下如何使用State。
<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/halo" minWidth="1024" minHeight="768">
<s:layout> <s:BasicLayout/> </s:layout> <s:states> <s:State name="default"/> <s:State name="Register"/> </s:states> <!-- Set title of the Panel container based on the view state.--> <s:Panel id="loginPanel" title="Login" title.Register="Register"> <s:layout> <s:VerticalLayout/> </s:layout> <mx:Form id="loginForm"> <mx:FormItem label="Username:"> <s:TextInput/> </mx:FormItem> <mx:FormItem label="Password:"> <s:TextInput/> </mx:FormItem> <mx:FormItem id="confirm" label="Confirm:" includeIn="Register"> <!-- Add a TextInput control to the form for the Register view state. --> <s:TextInput/> </mx:FormItem> <mx:FormItem direction="horizontal"> <!-- Use the LinkButton to change view state.--> <mx:Spacer width="100%" id="spacer1"/> <!-- Set label of the control based on the view state.--> <mx:LinkButton id="registerLink" label="Need to Register?" label.Register="Return to Login" click="currentState='Register'" click.Register="currentState=''"/> <s:Button id="loginButton" label="Login" label.Register="Register"/> </mx:FormItem> </mx:Form> </s:Panel> </s:Application> 定义状态flex4里状态的定义与flex3不同,你只需在<states></states>标签内定义状态就可以了。添加子元素和设置属性之类,不在这里进行了。如下所示:
<s:states>
<s:State name="State1"/> <s:State name="State2"/> <s:State name="State3"/> . . </s:states> 改变状态UIComponent类定义了一个currentState属性,通过改变这个属性的值来更换状态,这个属性的默认值是定义在需在<states></states>标签内的第一个状态。例如:
<s:Button id="b1" label="Change to State 1" click="currentState='State2';"/>
当然也可以通过UIComponent类的setCurrentState方法。
<s:Button id="b2" label="Change to the default" click="currentState='State1';"/> 为一个状态设定属性,样式和事件 这是与flex3很不同的地方。在flex4里通过点语法来设定一个组件属于某个状态的属性值。例如:
<s:Button label="Default State" label.State2="New State"/>
上述的代码的意思是,这个按钮的lable值在State2状态下是New State,在其他状态下是Default State。
上述代码也可以这样写:
<s:Button >
要想在某个状态里清除某个属性的值,可以让属性值等于@clear。如下:
<s:label>Default State</s:label> <s:label.State2>new State</s:label.State2> </s:Button> <Button color="0xFF0000" color.State1="@Clear"/> <s:Button id="b1" label="Click Me" click="ta1.text='hello';" click.State1="ta1.text='goodbye'"/> 添加或移除组件
在flex4里,添加或移除某个组件,直接在这组件的属性里搞定。组件多了两个属性,includeIn和excludeFrom。includeIn,表示这个组件要被添加到属性值所指的状态,excludeFrom,表示这个组件要从属性值所指的状态中删除,includeIn和excludeFrom不能在同一个组件标签里出现,他们的值可以是多个状态,之间用逗号隔开。例如:
<s:states> <s:CheckBox id="myCB" label="Checkbox" <s:TextArea text="Exclude from addTextInput" 更改一个组件的父元素一个组件的父元素也能变,你信吗?不过flex4真的做到了。用的就是这个<fx:Reparent>标签。还是看段代码吧!
<?xml version="1.0" encoding="utf-8"?>
这句话:<fx:Reparent target="setCB" includeIn="Parent2"/>什么意思呢?target的值setCB,就是我们要换父亲的组件就是setCB,看上面代码,你看它在哪里?setCB是第一个panel的Button的id吧!当转换到状态Parent2时,这个Button就成了第二个Panle的子元素。因为includeIn="Parent2"告诉我们了,在状态Parent2时,就要换了setCB的父元素,换成fx:Reparent的父元素,即第二个panel。
<!-- statesNewStatesReparent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark"> <s:layout> <s:VerticalLayout/> </s:layout> <s:states> <s:State name="Parent1"/> <s:State name="Parent2"/> </s:states> <s:HGroup> <s:Panel id="Panel1" height="100" width="100" title="Panel 1"> <s:Button id="setCB" includeIn="Parent1"/> </s:Panel> <s:Panel id="Panel2" height="100" width="100" title="Panel 2"> <fx:Reparent target="setCB" includeIn="Parent2"/> </s:Panel> </s:HGroup> <s:HGroup> <s:Button label="Parent 1" click="currentState='Parent1'" enabled.Parent1="false"/> <s:Button label="Parent 2" click="currentState='Parent2'" enabled.Parent2="false"/> </s:HGroup> </s:Application> 添加子元素时的控制 或许,你有这样的疑问。我为某个状态添加了一个子元素,这个元素在原来的状态是不存在的,至少,你看不见。那么,这个子元素时是在程序一运行时就被创建了还是在切换状态时才创建呢? 界面的改变不是仅仅只能通过State。通过导航器,如:Accordion,Tab Navigator,ViewStack containers你也能做到。到底用哪个,取决于你的应用需求以及用户界面的设计。 创建状态组在flex4里,可以给状态分组,比如第一个状态和第二个状态是一组,第三个状态和第四个状态是一组等等。我们先看怎么分组?
<s:State name="default"/>
只需添加一个stateGrooups这个属性。
<s:State name="addCheckBox" stateGroups="Group1"/> <s:State name="addTextInput"/> <s:State name="addCheckBoxandButton" stateGroups="Group1"/> 添加分组的好处是什么呢? 如果一个组件在多个状态中出现,你就可以把这些状态划分到一组。那么,当出现这个族里任何一个状态时,这个组件的设置都会有效。点语法后面的值可以是组的名称,excludeFrom和includeIn的值也可以使组的名称。 先写到这里,后续还会写些有关改变状态所触发的事件和实现让浏览器的前进后退按钮切换状态的功能的问题。 与状态有关的事件下面接收4个与状态有关的事件:
<?xml version="1.0"?> <!-- statesStatesSimpleEvent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark"> <s:states> <!-- Define the new view states. --> <s:State name="default" enterState="MyEnterTA.text = 'Enter state: default';" exitState="MyExitTA.text = 'Exit state: default';"/> <s:State name="NewButton" enterState="MyEnterTA.text = 'Enter state: NewButton';" exitState="MyExitTA.text = 'Exit state: NewButton';"/> </s:states> <s:VGroup id="g1"> <s:HGroup> <s:Button id="b1" label="Click Me" enabled.NewButton="false"/> <s:Button id="b2" label="New Button" includeIn="NewButton"/> </s:HGroup> <s:Button label="Change to NewButton state" click="currentState='NewButton';"/> <s:Button label="Change to default view state" click="currentState='default';"/> <s:TextArea id="MyEnterTA"/> <s:TextArea id="MyExitTA"/> </s:VGroup> </s:Application> 用浏览器切换状态 Flex browser manager能够让用户通过浏览器的前进后退按钮来导航应用。因为这个browser manager能够对状态的切换进行跟踪。 以前说过,每个状态是个新的界面,而不是一个新的页面。但是用浏览器也能实现不同状态之间的切换。如何做到呢?先看看背景知识。 BrowserManager:一个 Singleton 管理器,用于充当浏览器和应用程序之间的代理。使用它可以访问浏览器地址栏中的 URL,这与访问 JavaScript 中的 document.location 属性类似。它有一个getInstance() 方法,返回的是一个IBrowserManager类的实例。IBrowserManager:由 BrowserManager 的共享实例实现的接口。init()方法:初始化 BrowserManager。fragment属性:当前 URL 显示在浏览器地址栏中时,“#”之后的部分。 看个实例 <?xml version="1.0"?> <!-- statesStatesBrowserManager.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo" xmlns:s="library://ns.adobe.com/flex/spark" creationComplete="initApp();"> <fx:Script> <![CDATA[ import mx.managers.BrowserManager; import mx.managers.IBrowserManager; import mx.events.BrowserChangeEvent; import mx.utils.URLUtil; // The search string value. [Bindable] public var searchString:String; // 一个 BrowserManager 类的实例. private var browserManager:IBrowserManager; //在应用创建完成时初始化 BrowserManager. public function initApp():void { browserManager = BrowserManager.getInstance(); browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE,parseURL); browserManager.init("","Browser Manager for View States"); updateURL('default'); } // 当用户按前进后退按钮时触发事件,事件处理器从URL里接到状态的值,从而。用他 //设定当前状态。 private var stateFromURL:String; private function parseURL(e:Event):void { var o:Object = URLUtil.stringToObject(browserManager.fragment); stateFromURL = o.state; currentState=stateFromURL; } // 状态改变时改变地址。 private function updateURL(myCurrentState:String):void { var s:String = "state=" + myCurrentState; browserManager.setFragment(s); } // 当按下go按钮时执行该方法。 // 它会改变状态以及调用updateURL()方法来改变URL。 public function doSearch():void { currentState = "results"; updateURL('results'); searchString = searchInput.text; } // 点击reset按钮时执行该方法,该方法是状态改到默认值,。并且改变URL public function reset():void { currentState = ''; searchInput.text = ""; searchString = ""; updateURL('default'); } ]]> </fx:Script> <s:states> <!-- The state for displaying the search results --> <s:State name="default"/> <s:State name="results"/> </s:states> <!-- In the default state,just show a panel with a search text input and button. --> <s:Panel id="panel1" title="Search" title.results="Results" resizeEffect="Resize" width="10%" height="10%" width.results="100%" height.results="100%"> <s:layout> <s:VerticalLayout/> </s:layout> <s:SkinnableContainer id="searchFields" defaultButton="{b}"> <s:layout> <s:HorizontalLayout/> </s:layout> <s:TextInput id="searchInput"/> <s:Button id="b" label="Go" click="doSearch();"/> <s:Button includeIn="results" label="Reset" click="reset();"/> </s:SkinnableContainer> <s:SimpleText includeIn="results" text="Search results for {searchString}"/> </s:Panel> </s:Application> 有点长哦! 在这个实例中,当用户改变状态时,updateURL()就会将相应的地址写到浏览器的地址栏,当按浏览器的前进或者后退按钮时,parseURL()方法会从URL中获得当前状态值,并且改变状态。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Flash Builder4与Flash cs4 协同工作
- ruby-on-rails – Rails:has_many:through或has_many_and
- FLASH CS4 + PHP 开发一个FLASH简易聊天室
- ajax跨域
- [Swift]LeetCode524. 通过删除字母匹配到字典里最长单词 |
- c# – 如何使用EF6更新多个表
- c# – 在字典初始值设定项中使用方括号和花括号之间有区别吗
- Flex:Web报表引擎——MyReport 2.6.4.0新功能
- emacs – 我怎么可以diff一个单一的文件与magit?
- 前端与服务器分离开发出现跨域问题,jsonp与gulp-connect注