View state transition problem: effects don’t play

Published on: July 17, 2009
Categories: AIR, Flex
Comments: No Comments

Question:

When I’m using view states, I apply transitions to make the view state changes more fluent an attractive. There seems to be a problem though, because when I have a component in the second view state that I want to fade out upon returning to the base state, that effect is never played. Do you have a clue why this doesn’t happen and if there a solution for this problem?

Solution:

If you are using view states and want to apply certain transitions between these states, there are some things to keep in mind. When adding components to a state, the transition effects (also called behaviors) are applied to that component while adding it. So this means that the effects will be visible during initialization of the view state. However, when you go back to the original base state, the component is removed again before the effects have had the chance of being displayed. Luckily, in Flex there are a couple of ways of dealing with this issue.

The first way of making sure the effects are visible is to not make use of a transition when going back to the base state. Instead, you use the effect triggers of the component itself to trigger the effect. When the component is removed, you need to use the removedEffect trigger like in the following example:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
 
<!-- The font needs to be embedded for the texxt to fade out
as well. Otherwise, the button will fade, but the text
will simply remain fully opaque througout the effect -->
<mx:Style>
@font-face {
src: local("Verdana");
fontFamily: myFont;
fontWeight: bold;
}
 
global {
fontFamily: myFont;
}
</mx:Style>
 
<!-- This is the Fade effect we are going to use when the component is removed 
          from the display list -->
<mx:Fade id="fade" alphaFrom="1" alphaTo="0" duration="2000"/>
 
<!-- Define the view state -->
<mx:states>
<mx:State name="extraButton">
<mx:AddChild>
<!-- This button will fade in through the transitions and will fade out via the 
          removedEffect trigger -->
<mx:Button id="btn2" label="Click me now" click="currentState=''" removedEffect="{fade}"/>
</mx:AddChild>
</mx:State>
</mx:states>
 
<!-- Define the view state transition -->
<mx:transitions>
<mx:Transition fromState="" toState="extraButton">
<mx:Fade target="{btn2}" alphaFrom="0" alphaTo="1" duration="2000"/>
</mx:Transition>
</mx:transitions>
 
<!-- This component will be visible by default and triggers the second view state -->
<mx:Button id="btn1" label="Click me" click="currentState='extraButton'"/>
 
</mx:Application&gt;

The problem with this approach is that the transition effects are scattered throughout your code. However, there is also a second, in my opinion more appropriate way of dealing with this transition problem and that is through the use of transitions. This means that all of your transitional code will be located in 1 spot and this is so much easier to maintain.

But how do we solve the issue of the effect not being shown? Well, in fact (and this is not often mentioned in books and courses), you do have total control of when an item is being added or removed considering the effects that need to be played on the component. To do this, you can simply use the <mx:AddChildAction> and <mx:RemoveChildAction> tags. Just place them in the right order within a <ms:Sequence> tag after the appropriate effect and your effect will be displayed properly. Just take a look at this example code:<

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 
<!-- The font needs to be embedded for the texxt to fade out as well.
Otherwise, the button will fade, but the text will simply remain fully opaque
througout the effect -->
 
<mx:Style>
@font-face {
src: local("Verdana");
fontFamily: myFont;
fontWeight: bold;
}
 
global {
fontFamily: myFont;
}
</mx:Style>
 
<!-- Define the view state -->
<mx:states>
<mx:State name="extraButton">
<mx:AddChild>
<!-- This button will fade in and out through the transitions -->
<mx:Button id="btn2" label="Click me now" click="currentState=''"/>
</mx:AddChild>
</mx:State>
</mx:states>
 
<!-- Define the view state transition -->
<mx:transitions>
<mx:Transition fromState="" toState="extraButton">
<mx:Fade target="{btn2}" alphaFrom="0" alphaTo="1" duration="2000"/>
</mx:Transition>
 
<!-- The fade out effect is accomplished by adding a sequence with the 
          RemoveChildAction after the effect -->
<mx:Transition fromState="extraButton" toState="">
<mx:Sequence target="{btn2}">
<mx:Fade alphaFrom="1" alphaTo="0" duration="2000"/>
<mx:RemoveChildAction/>
</mx:Sequence>
</mx:Transition>
</mx:transitions>
 
<!-- This component will be visible by default and triggers the second view state -->
<mx:Buttonid="btn1" label="Click me" click="currentState='extraButton'"/>
 
</mx:Application>

You can view the results of the latter solution in the application below.

This movie requires Flash Player 9

No Comments - Leave a comment

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>


Welcome , today is Sunday, March 26, 2017