Is there a Flex 4 Spark version of the Pause effect?
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/effects/Pause.html
In a Sequence this effect pauses for a specific duration of time before going to the next effect. It also can pause until a specific event is dispatched on a target.
#Shaun,
I see. What threw me off was the mx.effects package it's part of and this comment in the TweenEffect class which Pause extends.
/**
* TweenEffect is the superclass for the animated effects in Flex 3. As of Flex 4, the
* Spark effects extend the spark.effects.Animate class instead of TweenEffect.
*/
[Alternative(replacement="spark.effects.Animate", since="4.0")]
Thank you!
It says here although it's not advised (likely due to the changes in the architecture to separate the layout and scroll bar etc.)
http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf5fdc3-7fff.html
I would guess a Pause effect would work fine... actually tried it out it shows up in Spark in the 4.5 SDK
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="HomeView">
<fx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
bc.visible=true;
}
protected function button2_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
bc.visible=false;
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:Sequence id="sq">
<s:Rotate angleBy="45" autoCenterTransform="true"/>
<s:Pause duration="1000"/>
<s:Rotate angleBy="45" autoCenterTransform="true"/>
</s:Sequence>
</fx:Declarations>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:BorderContainer id="bc" width="100" height="100" backgroundColor="blue" visible="false" showEffect="sq"/>
<s:Button click="button1_clickHandler(event)" label="show"/>
<s:Button click="button2_clickHandler(event)" label="hide"/>
</s:View>
Note this is a mobile application hence the s:View.
Related
how to I pass in a uicomponent to a mxml custom component?
ex: I want to pass in any number of buttons, and I want my custom component to lay them out in a certain order.
MainApp.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"
minWidth="955" minHeight="600" xmlns:local="*"
>
<local:myComp >
<s:Button label='Button1' />
<s:Button label='Button2' />
<!--I want to add anything else here -->
</local:myComp>
myComp.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()"
width="400" height="300"
>
<fx:Script>
<![CDATA[
private function init():void {
// how do I access the added components and place them where I want?
// do I use removeChildren and AddChildren?
// addItemsHere.addchild(nextButton);
]]>
</fx:Script>
<s:HGroup id='addItemsHere' />
As your component extends Group, you shall use addElement instead of addChild (and for all other methods with 'child' in their name it shall be replaced with 'element'. So, access to all elements will be like that:
for(var i:int =0; i < numElements; i++){
var button:Button = Button(getElementAt(i));
doWhatIWantWithMyButton(button);
}
It is also better to override createChildren method of your component if you know what to add at the creation moment.
If you don't need very specific button placement, you can set layout property of your component to any desired layout (like VerticalLayout, for example), and those layouts are tunable.
You seem to be trying to recreate functionality that already exists in the SDK. This is wat SkinnableContainer is for.
Depending on your use case, there are two ways to use it:
You only need to add some custom graphic elements to you custom component, but no additional behaviour
In this scenario, you would simple reuse SkinnableContainer and assign it a custom skin, like so:
<s:SkinnableContainer skinClass="MySkin">
<s:Button label='Button1' />
<s:Button label='Button2' />
</s:SkinnableContainer>
With MySkin.mxml perhaps something like:
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Metadata>
[HostComponent("spark.components.SkinnableContainer")]
</fx:Metadata>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<s:layout>
<s:VerticalLayout/>
</s:layout>
<s:Label text="I'm a SkinnableContainer"/>
<s:Group id="contentGroup" width="100%" height="100%">
</s:SkinnableContainer>
Your Buttons will now automatically be added to the contentGroup; the SkinnableContainer class handles this for you. Note that this Group must have exactly that id; it's a required SkinPart.
You want to add some behaviour to you component
The procedure is the same, but you would now subclass SkinnableContainer (this is usually done in pure ActionScript), write some behaviour in there, and assign the skin to an instance of this class.
public class MyComp extends SkinnableContainer {
//additional behaviour goes here
}
Usage:
<local:MyComp skinClass="MySkin">
<s:Button label='Button1' />
<s:Button label='Button2' />
</local:MyComp>
is there an built in method in spark tile list to get an item from a given point?
Thanks
As #www.Flextras.com suggested, looking at the source code can be useful. TileLayout has a method named getElementNearestScrollPosition() that will give you the index of the element that is located closest to a Point that you specify. This method is hidden in Flex's mx_internal namespace, however, so it gets excluded from the ASDocs.
Here's a simple example that seems to be working. I'm not showing the itemRenderer.
Main.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" xmlns:local="*">
<fx:Script>
<![CDATA[
import mx.core.mx_internal;
use namespace mx_internal;
protected function list1_clickHandler(event:MouseEvent):void
{
var localPointInList:Point = list.globalToLocal(new Point(event.stageX, event.stageY));
trace(tileLayout.getElementNearestScrollPosition(localPointInList));
}
]]>
</fx:Script>
<fx:Declarations>
<s:ArrayCollection id="foo">
<fx:Object date="Jan 1, 2012"/>
<fx:Object date="Jan 1, 2013"/>
<fx:Object date="Jan 1, 2014"/>
</s:ArrayCollection>
</fx:Declarations>
<s:layout>
<s:HorizontalLayout />
</s:layout>
<s:Button label="I'm a button"/>
<s:List id="list" dataProvider="{foo}" itemRenderer="TestRenderer" click="list1_clickHandler(event)">
<s:layout>
<s:TileLayout id="tileLayout" requestedColumnCount="2" />
</s:layout>
</s:List>
</s:Application>
Note that I'm doing some conversion between local and global coordinates. You need to do this convert the global coordinates in the MouseEvent to the coordinate space of the List. I've also added a Button to the main app, solely to test this conversion ... the presence of the button makes it so the list's local coordinates do not match the global coordinates. If the list was placed at the origin (0,0) this conversion between coordinate spaces would not be necessary ... but that rarely happens in real world apps.
I have created my first animation effect in flex 4. Its a very simple animation within my custom component which moves a label component left to right to left 3-5 times and then fades out gradually.
Every thing works fine but the problem is that when I run the animation first time, it plays jerky animation and perfect smoother after wards. I dont know why.
Can some one tell whats wrong with this?
This is the full source code of my custom component. After adding it to the stage, calling the showProgressEffect() will play the animation.
Notice that I have made the label "cacheAsBitmap" to avoid flickers while moving the label and call to stop() before play() methods of each of the animations/effects.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="274" height="72"
click="onClick()" xmlns:components="ui.hud.components.*" cacheAsBitmap="true">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<s:Sequence id="tween" repeatCount="5" effectEnd="onEffectEnd()" >
<s:Move xBy="20" duration="500" />
<s:Move xBy="-20" duration="500" xFrom="50"/>
</s:Sequence>
<s:Fade id="fadeEffect" alphaTo="0" duration="2000" />
</fx:Declarations>
<fx:Script>
<![CDATA[
[Bindable]
public var questId:int;
[Bindable]
public var questTitle:String;
[Bindable]
public var iconUrl:String;
private function onClick():void{
Globals.questCtr.showQuest(questId);
}
private function onEffectEnd():void{
fadeEffect.stop();
fadeEffect.play([lblStatus]);
}
public function showProgressEffect():void{
tween.stop();
lblStatus.alpha = 1;
tween.play([lblStatus]);
}
]]>
</fx:Script>
<mx:Image source="{iconUrl}" width="75" height="75"/>
<s:Group x="77" y="24" width="197">
<s:Label id="lblStatus" text="Task Complete" fontWeight="bold" fontSize="25" alpha="0" cacheAsBitmap="true" hideEffect="" mouseEnabled="false"/>
</s:Group>
</s:Group>
This happens because before animation start your label is in different position, than after it. I don't know what exactly you trying to achieve, but there are two choices:
You can change xFrom="50" to xFrom="20"in second move effect;
You can change lblStatus x coordinate to 30;
I have an AIR application. It should be moved around the screen with the mouse. In order to achieve this I use the event:
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, true,-2);
It should be activated with the lowest priority compared to inserted elements for example those that should be scrolled, clicked, etc.
I tried the solution shown below with the event priority set to -1 because there might happen 2 different events and my moving application event should be the last one to be serviced or shouldn't be serviced at all.
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="200"
height="200"
applicationComplete="init()">
<fx:Script>
<![CDATA[
import mx.core.Window;
import mx.events.ScrollEvent;
private function init():void {
this.stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, true,-2);
}
private function onMouseDown(event:MouseEvent):void {
trace("clicked on stage "+event.currentTarget.toString());
if(event.currentTarget == stage){
trace("catched stage target");
this.nativeWindow.startMove();
event.stopImmediatePropagation();
}
}
function scrolledCanvasHandler(event:ScrollEvent){
trace("clicked on canvas "+event.currentTarget.toString());
event.stopPropagation();
}
]]>
</fx:Script>
<mx:Canvas x="29" y="34" width="80%" height="80%" backgroundColor="#343434" scroll="scrolledCanvasHandler(event)">
<mx:Label x="25" y="77" text="moving window, moving window"
fontSize="18" color="#FFFFFF" fontWeight="bold"/>
</mx:Canvas>
</s:WindowedApplication>
As you will notice the
event.stopPropagation();
doesn't work.
Perhaps my solution isn't the best suited to achieve this. Are there better solutions?
Chris
that's what i did in an app of mine:
<s:HGroup id="appTitleBar"
width="100%" height="35"
styleName="titleBar"
mouseDown="nativeWindow.startMove();"
doubleClickEnabled="true"
doubleClick="nativeWindow.minimize();"
contentBackgroundColor="#313131"/>
click (+drag) on this HGroup will drag the window. duobleclick will minimize it.
edit
don't make your whole app draggable this will only confuse the user.
and btw priority should be positive not negative - but also don't mess with this. not expected behavior for anyone.
How can we navigate within an itemRenderer?
For example, in Views we use the View.navigator (ViewNavigator) to push and pop views, there is no such feature in ItemRenderer.
Navigation within a View (Easy)
<s:View>
<s:HGroup >
<s:Button label="Questionnaire" click="navigator.pushView(view.QuestionnaireCategory1View)"/>
</s:HGroup>
Navigation within a Item Renderer (Impossible?)
<?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"
autoDrawBackground="true" height="56">
<s:HGroup>
<s:Button text="Button" click="?????????"/>
</s:HGroup>
</s:ItemRenderer>
You want to use bubbling events to catch when the user interacts with an item renderer.
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:HGroup>
<s:Button text="Button" click="dispatchEvent(new Event('buttonClicked', true));"/>
</s:HGroup>
</s:ItemRenderer>
Then when do this with whatever is using your item renderer:
<DataGroup id="group" itemRenderer="YourItemRenderer" dataProvider="{someData}" creationComplete="group.addEventListener('buttonClick', someHandlerFunction);" />
And then within your handler function, do whatever action you wanted to do. In this case, I'm adding the event listener on creation complete of the DataGroup, but you can add it to the creation complete event of the main container. This way you keep your item renderer decoupled and reusable, as well as using proper software practices (data in, events out).
In when you create your itemRenderer
<comp:MyItemRenderer navigator="{navigator}"/>
In your itemRenderer (here call MyItemRenderer)
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
autoDrawBackground="true" height="56">
<fx:Script>
<![CDATA[
import spark.components.ViewNavigator;
private var _navigator:ViewNavigator;
public function set navigator(value:ViewNavigator):void
{
_navigator = value;
}
]]>
</fx:Script>
<s:HGroup>
<s:Button label="Button" click="{_navigator.pushView(view.QuestionnaireCategory1View)}"/>
</s:HGroup>