使用 Flex ViewStack 重新创建/重置视图
Posted
技术标签:
【中文标题】使用 Flex ViewStack 重新创建/重置视图【英文标题】:Recreating/resetting views with Flex ViewStack 【发布时间】:2010-10-09 03:06:02 【问题描述】:我正在为不同的应用程序状态编写一个使用 ViewStack 的 Adobe AIR 应用程序。有没有办法确保每个视图组件在每次显示/隐藏时都被创建/销毁?
例如,如果我在视图中有一个 TextInput,我希望它在每次切换到该视图时重置为初始状态,而不是之前输入的文本。或者,如果我有一个计时器,我希望它在我离开视图时被销毁,这样当我在应用程序的不相关部分时它就不会继续运行。我知道我可以手动初始化/销毁 show() 和 hide() 事件中的所有内容,但有更简单的方法吗?
【问题讨论】:
【参考方案1】:AFAIK 没有内置的方法来执行此操作,因此您必须手动处理您提到的显示和隐藏事件。
ViewStack 确实有两种方法“saveState”和“loadState”也许可以帮助您解决这个问题。历史管理器使用这些方法来启用后退/前进导航。不过,文档似乎没有任何示例。
【讨论】:
【参考方案2】:在创建/删除策略和管理状态方面,ViewStacks 可能是魔鬼的工作。我们在开发法定 ecoDrive 时遇到了各种各样的问题,大约 3/4 的时候我们都非常反对 ViewStacks 来管理我们应用程序中的视图状态。
但是... 一个不错的选择是首先将 creationPolicy 设置为 ContainerCreationPolicy.NONE。这样,您可以控制何时在 ViewStack 中创建任何面板。然后我认为您需要某种逻辑,以便当 ViewStack 更改面板时,它会删除或重置您所在的面板。
另一个可行的替代方法是使用视图状态。有一个作为主容器的基本状态,然后是每个部分的简单状态。这样,当您切换到新状态时,旧状态会以与其创建方式相反的顺序被删除。你必须对状态进行自律,因为当它们开始嵌套时,它们最终会变得非常复杂和混乱。如果您保持简单,它可能会按您的需要工作。
【讨论】:
【参考方案3】:两个答案都是正确的——似乎没有任何内置的方法可以做到这一点。我通过为我的视图组件创建一个“包装器”组件解决了这个问题。每次显示视图时,它都会创建一个新的视图组件。这并不理想,但很好地满足了我的要求,并且需要对我的应用程序结构进行少量更改。
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" show="init()" hide="cleanup()">
<mx:Script>
<![CDATA[
private var myComponent:MyComponent;
private function init():void
myComponent = new MyComponent();
componentContainer.addChild(myComponent);
private function cleanup():void
componentContainer.removeAllChildren();
]]>
</mx:Script>
<mx:Canvas id="componentContainer" />
</mx:Canvas>
【讨论】:
【参考方案4】:将您的“视图”构建为单独的模块,然后使用 ViewStack 在它们之间切换。然后,您可以编写一个函数来在触发 ViewStack 的“更改”事件时销毁未使用的模块(根据 selectedChild 属性检查每个模块)。
2¢
【讨论】:
【参考方案5】:我为我的不同观点使用不同的状态。在每次状态更改时,我都会添加和删除组件。
这会导致UIComponent
触发的add
和remove
事件,这使我可以在每次添加组件时对其进行初始化和清理。
这就是想法……
<mx:states>
<mx:State name="state1">
<mx:AddChild>
<mx:SomeUIComponent id="myComp" add="myComp.initialize()" remove="myComp.cleanup()"/>
</mx:AddChild>
</mx:State>
</mx:states>
【讨论】:
【参考方案6】:在 MXML 2009 中,您可以使用 itemDestructionPolicy="auto" 在使用后销毁组件。如果在具有两种状态(init、logged)的第一个视图组件中使用此属性,则可以销毁并重新初始化所有子视图组件。示例:
<s:states>
<s:State name="init" />
<s:State name="logged" />
</s:states>
<s:SkinnableContainer id="skincon" backgroundAlpha="0"
backgroundColor="#FFFFFF">
<s:VGroup id="MainContainer" paddingTop="0"
paddingLeft="20" paddingRight="20" gap="0">
<views:_HeaderView id="header" />
<mx:ViewStack id="viewStack" >
<s:NavigatorContent includeIn="init" itemDestructionPolicy="auto">
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle" />
</s:layout>
<views:LoginView title="Login" id="loginView" />
</s:NavigatorContent>
<s:NavigatorContent includeIn="logged" itemDestructionPolicy="auto">
<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="top" />
</s:layout>
<views:_CentralView id="userView" />
</s:NavigatorContent>
</mx:ViewStack>
<views:_FooterView id="footer" />
</s:VGroup>
</s:SkinnableContainer>
【讨论】:
以上是关于使用 Flex ViewStack 重新创建/重置视图的主要内容,如果未能解决你的问题,请参考以下文章
egret:ViewStack 中的scroller滚动条的隐藏