使用Flex ViewStack重新创建/重置视图

时间:2009-02-22 04:35:53

标签: flex flash air

我正在使用ViewStack为不同的应用程序状态编写Adobe AIR应用程序。有没有办法确保每次显示/隐藏每个视图组件时都会创建/销毁它?

例如,如果我在视图中有TextInput,我希望每次更改到该视图时它都会重置为其初始状态,而不是之前输入的文本。或者,如果我有一个Timer,我希望它在我离开视图时被销毁,这样当我在应用程序的一个不相关的部分时它就不会继续运行。我知道我可以手动初始化/销毁show()和hide()事件中的所有内容,但有更简单的方法吗?

6 个答案:

答案 0 :(得分:1)

AFAIK没有内置的方法来执行此操作,因此您必须通过处理显示和隐藏事件来手动执行此操作。

然而,ViewStack有两种方法“saveState”和“loadState”可能会帮助你解决这个问题。历史记录管理器使用这些方法来启用后退/前进导航。但是,这些文档似乎没有任何示例。

答案 1 :(得分:1)

在创建/删除策略和管理状态时,ViewStacks可能是魔鬼的工作。当我们开发法国ecoDrive时,我们遇到了各种各样的问题,虽然我们在应用程序中对视图状态的管理都非常反ViewStack,但我们已经解决了大约3/4的问题。

但是......一个好的选择是首先将creationPolicy设置为ContainerCreationPolicy.NONE。这样就可以控制何时在ViewStack中创建任何面板。然后我认为你需要有一些逻辑,以便当ViewStack更改一个面板时,它会删除或重置你所在的面板。

另一种可行的替代方案是使用视图状态。有一个基本状态作为主要容器,然后是每个部分的简单状态。这样,当您切换到新状态时,旧状态将按照与创建状态相反的顺序删除。你必须对各州保持纪律,因为当他们开始变得嵌套时,他们最终会变得非常复杂和混乱。如果你保持简单,它可以按你的要求工作。

答案 2 :(得分:1)

在MXML 2009中,您可以使用itemDestructionPolicy =“auto”在使用后销毁组件。如果在具有两个状态(init,logged)的第一个视图组件中使用此属性,则可以销毁并重新初始化所有子视图组件。示例:

   <s:states>
    <s:State name="init" />
    <s:State name="logged" />
  </s:states>

  <s:SkinnableContainer id="skincon" width="100%" height="100%" backgroundAlpha="0"
                        backgroundColor="#FFFFFF">
    <s:VGroup id="MainContainer" width="100%" height="100%" paddingTop="0"
              paddingLeft="20" paddingRight="20" gap="0">
      <views:_HeaderView id="header" />
      <mx:ViewStack id="viewStack" width="100%" height="100%">
        <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>

答案 3 :(得分:0)

两个答案都是正确的 - 似乎没有任何内置方法可以做到这一点。我通过为视图组件创建“包装器”组件来解决问题。每次显示视图时,它都会创建一个新的视图组件。这不是理想的,但很好地符合我的要求,并且我的应用程序结构几乎没有变化。

<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 width="100%" height="100%" id="componentContainer" />
</mx:Canvas>

答案 4 :(得分:0)

将“视图”构建为单独的模块,然后使用ViewStack在它们之间切换。然后,当ViewStack的“更改”事件被触发时,您可以编写一个函数来销毁未使用的模块(根据selectedChild属性检查每个模块)。

答案 5 :(得分:0)

我对不同的观点使用不同的状态。在每次状态更改时,我添加和删除组件。

这导致add fire的removeUIComponent事件,这使我可以在每次添加时初始化和清理我的组件。

这就是想法......

   <mx:states>
      <mx:State name="state1">
         <mx:AddChild>
            <mx:SomeUIComponent id="myComp" add="myComp.initialize()" remove="myComp.cleanup()"/>
         </mx:AddChild>
      </mx:State>
   </mx:states>