I am trying to understand how to make Flex transitions behave in an attractive smooth manner. I can't get them to work without them appearing extremely choppy.
I have attached a silly demonstration application to illustrate this. It shows a List which has a custom ItemRenderer. When an item in the list is selected, the TextInput should slowly grow wider. When an item is deselected, the TextInput should slowly shrink.
There are 2 issues with this implementation which make it look ugly. These can be seen by clicking about on the List to make the items animate. These issues are:
When an item is animating but enters the "hovered" state, the TextInput snaps back to the small size. Why is this?
When an item has its animation interrupted it snaps to either the largest or smallest size and then starts animating, rather than continuing the animation from its current value. Why?
Any help greatly appreciated.
Thanks, Phil TestApplication.mxml
<?xml version="1.0" encoding="utf-8"?>
<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"
initialize="init(event)"
minWidth="900" minHeight="600">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
protected function init(event:FlexEvent):void {
var ac:ArrayCollection = new ArrayCollection();
ac.addItem("A1");
ac.addItem("B2");
ac.addItem("C3");
myList.dataProvider = ac;
}
]]>
</fx:Script>
<s:List id="myList" width="410" height="350" itemRenderer="MyItemRenderer" requireSelection="true"/>
</s:Application>
MyItemRenderer.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true">
<s:states>
<s:State name="normal" />
<s:State name="hovered" />
<s:State name="selected" />
</s:states>
<s:transitions>
<s:Transition fromState="*" t开发者_JS百科oState="selected" id="itemHasBeenSelected" >
<mx:AnimateProperty property="width" toValue="300" duration="3000" target="{textInput}" />
</s:Transition>
<s:Transition fromState="selected" toState="*" id="itemHasBeenUnselected">
<mx:AnimateProperty property="width" toValue="100" duration="3000" target="{textInput}" />
</s:Transition>
</s:transitions>
<s:Group width="100%">
<s:Label text="{data}" color.selected="red" color.normal="black"/>
<s:TextInput x="100" id="textInput" width="100"/>
</s:Group>
</s:ItemRenderer>
To answer your questions, but in the opposite order:
(2) You want to use the autoReverse
capability which is a property of the spark Transition. You could do this by just adding autoReverse="true"
to your current transitions, but I'd also suggest simplifying them to the following single Transition, and use the Spark Resize effect instead of the MX AnimateProperty:
<s:Transition autoReverse="true">
<s:Resize target={textInput}" duration="3000"/>
</s:Transition>
Then, if you define the values for the width
on the component itself, the transition will take care of the rest:
<s:TextInput x="100" id="textInput" width.normal="100" width.selected="300"/>
That should take care of the "popping" between the values of the normal
and selected
states. As for the hovering issue:
(1) If you check out Chet Haase's video on Adobe TV on Auto-Reversing Transitions, he states that one of the major caveats or shortfalls in the auto-reversing architecture is that it only handles transitions from A->B and B->A. If you try to attempt to transition to a third state (in your case "hovered"), the auto-reversing will fail. Unfortunate, but at least we have the auto-reversing, which wasn't even an option in Flex 3.
HOWEVER, there is a workaround, at least for the simple ItemRenderer that you posted: Try removing the hovered
state altogether.
<!--s:State name="hovered" /-->
As long as you don't plan on doing anything else special in the ItemRenderer during a hovered state, this should work fine, and it will get rid of the popping between the states.
精彩评论