Archive for the ‘Examples’ Category
Running LCDS/BlazeDS in the cloud with AWS Elastic Beanstalk
Very recently I was looking for a simple and affordable solution to host Java-based services for the mobile version of my LCDS Samples application. Unfortunately, with the Java development, life is not as easy as with PHP where you can get affordable hosting that is managed and secured by your hosting provider. The reality is that with Java you usually end up having a VPS or an instance of a dedicated Linux server (of course Windows would work also). This is certainly a very good solution that gives you a lot of flexibility but you have to remember that the tasks of administering and securing your box are usually on your shoulders. Although I have some knowledge of Unix-type systems, to be honest I wouldn’t feel comfortable doing the whole administration on my own.
So after some research and trying out different options I ended up with an AWS Elastic Beanstalk service provided by Amazon (you can see it in action running here). I’m really excited about this service because it provides an instance of Tomcat (both 6.x and 7.x versions are available) hosted and managed on Amazon’s cloud infrastructure. On top of that and out-of-the-box, it provides a load balancer that will automatically launch additional instances if your application encounters the increased load. Also you have full access to your Tomcat logs and you can receive email notifications with the status and health of your running services. Another important thing is that it is extremely easy to use, especially when you install the AWS Eclipse plugin that can also work well with Eclipse/Flash Builder.
The good thing is that the cost of all this is not really high, the entry level service is just about $35.27 a month, more details about pricing are available here.
Getting started
Follow these steps to get up and running:
- Get an account (if you don’t already have one) with AWS (Amazon Web Services). Once you get an account you can sign up for Elastic Beanstalk via the “Manage Your Account” section.
- Configure your IDE environment. By default Flash Builder comes with a standard version of Eclipse that has only the JDT available. I suggest downloading the Eclipse IDE for Java EE Developers and to configure FB with this environment. It will give you additional tools to handle Tomcat instances and Java Web Projects, which you can use when developing for Elastic Beanstalk. Configuring FB with a custom installation of Eclipse is really straightforward. Once you download Eclipse from here and you extract it somewhere to your hard drive, you can go to the folder where you have FB installed and find the Adobe Flash Builder 4.5 Plug-in Utility application located in the utilities folder. In my case it is here “/Applications/Adobe Flash Builder 4.5/utilities/Adobe Flash Builder 4.5 Plug-in Utility.app” but it all depends where you have your FB installation and also on what OS you are on. Run this application and it will guide you with a few simple steps through the whole Flash Builder – Eclipse integration process.
- Install the AWS Eclipse plugin. This can be done directly from Eclipse. Just go to the Help -> Install New Software menu and enter the following update site URL: http://aws.amazon.com/eclipse

- Create a new AWS Java Web Project. After a successful install of the AWS plugin you will have an option to create new AWS projects. Use the wizard available from the top bar of Eclipse (with an AWS icon on it) to create a New AWS Java Web Project. First you will need to enter a project name, and credentials like Access Key ID and Secret Access Key. These values are generated when you sign up for an AWS account and you can copy them from the Security Credentials section of your AWS account.

You can select the Basic Java Web Application option (see the screenshot above), this will be enough for the LCDS/BlazeDS scenario. More info about other options is available through this site, with an in-depth video tutorial. - Configure the LCDS/BlazeDS environment. In order to do that you need to, copy all necessary jars into the WebContent/WEB-INF/lib folder of the newly created project. In my case I used a turnkey installation of LCDS and I just copied jars from the lcds-samples application and also jars from tomcat/lib/activemq4.1.1, tomcat/lib/jotm2.0.10 and tomcat/lib/lcds (this wouldn’t be necessary for BlazeDS but for LCDS it was required to make the DataServices and Messaging work properly). Next you will also need to copy all configuration files from the WEB-INF/flex folder and the web.xml that has all necessary LCDS/BlazeDS servlets/listeners configured. The important thing to note here is that by default the AWS Elastic Beanstalk service enables only port 80 and HTTP channels; in order to enable other ports that could be required for RTMP channels you can modify the AWS EC2 Security group settings (but that is a topic for another blog post and I will not cover it here). Another solution you have is to stick to the default settings and to configure LCDS services to use only HTTP channels; this is actually what I did for my lcds.riaspace.comservice. One last thing I had to do to make the LCDS function properly was to create a WebContent/META-INF/context.xml file in which I defined the transaction configuration as in the following snippet:
<?xml version="1.0" encoding="UTF-8"?> <Context reloadable="true"> <Transaction factory="org.objectweb.jotm.UserTransactionFactory" jotm.timeout="60"/> </Context>
- Deploy your application to the cloud. Once you have the configuration completed and all the services built you can deploy your application directly from Eclipse. Just right-click on the project and select the Amazon Web Services -> Deploy to AWS Elastic Beanstalk… option. Another wizard will pop up that will ask you to specify names for your application and environment.
Next you will need to select the server type, which would be AWS Elastic Beanstalk for Tomcat 6 (you also have the option to deploy to Tomcat 7 instances).
At last you will be able to specify the CNAME of your server (you can assign your own domain name in the DNS configuration, that is actually what I used to get the default lcds-samples.elasticbeanstalk.com configured as lcds.riaspace.com). Another valuable option here is to enter your email address, which will receive notifications of any changes to the service’s state and health.
Now you are ready to click the Finish button and it will start uploading and configuring your application in the cloud. Be aware that this process may take several minutes the first time. Once it is done you will be able to access your services via the following URL: http://yourcname.elasticbeanstalk.com. To redeploy any changes made to your services you just need to follow this last step all over again.
Ported LCDS Samples in Android Market
You may remember one of my previous posts about LCDS Messaging on tablet devices, well I went further with porting these demos and this time I brought also: CRM, Inventory Management and Notes to tablets. Not only I ported these but I also published it to Android Market for anyone to give it a try.
The app that has all the demos is called “Adobe LCDS Samples” and is available here (be aware that I applied market filter to restrict it only to tablets, I managed to do this with . <supports-screens /> Android specific tag in *-app.xml)
The hosted LCDS Samples service is located here and you may use it to play around with those samples (the service is thanks to Greg Wilson fellow Adobe Evangelist). UPDATE 2011-07-04: I moved the service to AWS Elastic Beanstalk serivce (blog post about will come soon) and it is now hosted here. The one I really like the most is a Dashboard app because it is easy to use and it shows nicely/visually the real-time capabilities of LiveCycle Data Services (LCDS).
Samples source code is available here in GitHub.
Below you can see few screenshots of the application running on my Motorola XOOM:
iOS style buttons in Flex 4.5 mobile applications
Ever wondered how you can make Flex 4.5 ActionBar buttons look like native buttons on iOS? This is actually very simple to achieve, what you need are just a few lines of CSS code. Checkout the snippet below:
/* CSS file */ @namespace s "library://ns.adobe.com/flex/spark"; @media(os-platform:"IOS") { s|ActionBar { defaultButtonAppearance:beveled; } .backButton { skinClass:ClassReference("spark.skins.mobile.BeveledBackButtonSkin"); } }
As you can see in the code above I also used CSS media queries to have the proper style and skin class applied only when running on iOS devices. Below you can see the end result:

The code that implements the view above is as simple as this:
<?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="iOS buttons"> <s:navigationContent> <s:Button label="Back" styleName="backButton"/> </s:navigationContent> <s:actionContent> <s:Button label="Button"/> </s:actionContent> </s:View>
LCDS Messaging on tablet devices
Recently I wanted to try the LiveCycle Data Services (LCDS) messaging feature on tablet devices. LCDS is a platform that lets you easily integrate Flash/Flex/AIR RIAs with JEE back ends, giving your applications full real-time capabilities on the web.
In order to run my tests I ported one of the LCDS demo apps that is included in the package to Flex 4.5 and published it to Motorola XOOM (running Android 3.1), BlackBerry PlayBook and the iPad. You can watch the results in the video below.
OAuth authorization with Flash and Flex apps
Below you will find links to my two video tutorials about OAuth authorization with Flash and Flex apps:
1) Introduction to OAuth for secure user and application authorization
2) OAuth in Adobe AIR applications built with Flash or Flex
You can also download example code from here.
Packaging AIR application for iOS devices with ADT command and ANT script
As you may know AIR 2.6 SDK was released yesterday. It brings a lot of improvements especially for iOS devices (you can find the release information here). Now if you already have a certificate and provisioning profile from Apple and want to try out your existing code to deploy on an iOS device you can use the following ADT command:
[AIR_SDK_HOME]/bin/adt -package -target ipa-test -provisioning-profile [MOBILE_PROVISION_FILE_PATH] -storetype pkcs12 -keystore [CERTIFICATE_FILE_PATH] ./MyApplication.ipa ./bin-debug/MyApplication-app.xml -C ./bin-debug MyApplication.swf -C ./bin-debug assets
Of course, replace the capitalized blocks with your appropriate paths, and then execute it from the root folder of your AIR application project. It will package the app SWF file and any accompanying assets from the bin-debug folder. Bear in mind that this is not a final build ready to be published to the App Store. In order to do that you want to package a release build from the bin-release folder and also use ipa-app-store target parameter instead of ipa-test. UPDATE: Flash Builder may overwrite an application ID in -app.xml with a “.debug” suffix; you should remove it prior to packaging. The ID should match the one registered with your mobile provisioning.
You can achieve the same thing with the following ANT script:
<?xml version="1.0" ?> <project> <!-- SDK properties --> <property name="SDK_HOME" value="PATH TO AIR SDK"/> <property name="ADT.JAR" value="${SDK_HOME}/lib/adt.jar"/> <!-- Project properties --> <property name="APP_NAME" value="MyApplication"/> <property name="APP_ROOT_DIR" value="."/> <property name="BUILD_DIR" location="${APP_ROOT_DIR}/bin-debug"/> <property name="APP_ROOT_FILE" value="${APP_NAME}.swf"/> <property name="APP_DESCRIPTOR" value="${APP_NAME}-app.xml"/> <property name="IPA_NAME" value="${APP_NAME}.ipa"/> <property name="STORETYPE" value="pkcs12"/> <property name="KEYSTORE" value="PATH TO YOUR CERTIFICATE"/> <property name="STOREPASS" value="CERTIFICATE PASSWORD"/> <property name="PROVISIONING_PROFILE" value="PATH TO PROVISIONING PROFILE FILE"/> <target name="package"> <java jar="${ADT.JAR}" fork="true" failonerror="true"> <arg value="-package"/> <arg value="-target"/> <arg value="ipa-test"/> <arg value="-provisioning-profile"/> <arg value="${PROVISIONING_PROFILE}"/> <arg value="-storetype"/> <arg value="${STORETYPE}"/> <arg value="-keystore"/> <arg value="${KEYSTORE}"/> <arg value="-storepass"/> <arg value="${STOREPASS}"/> <arg value="${APP_ROOT_DIR}/${IPA_NAME}"/> <arg value="${BUILD_DIR}/${APP_DESCRIPTOR}"/> <arg value="-C"/> <arg value="${BUILD_DIR}"/> <arg value="${APP_ROOT_FILE}"/> <arg value="-C"/> <arg value="${BUILD_DIR}"/> <arg value="assets"/> </java> </target> </project>
Slide effect with ViewStack and state transitions
In this post I want to explain how the slide effect can be applied to application views. My goal is to do it in a declarative way as much as possible and to use default Flex components. I will demonstrate two possible solutions, one using the ViewStack component and other using Flex states and transitions.
You may wonder why I put that much effort into the slide effect. Ok, I know this isn’t anything revolutionary and this type of user experience is quite common, but I think recently it has become even more popular. This is due to the fact that it is almost a standard type of view transition effect on mobile devices. Now why not try to bring some of the coolness of mobile interactions also to the desktop world?
Using the ViewStack component
In my previous post about the as3viewnavigator library I briefly mentioned a ViewStack component and its inability to display two views at the same time. The consequence of this is also an inability to have a slide effect similar to the one in ViewNavigator. It’s not that the slide effect is not possible at all but you can’t have two views slide together. The only available option in the default ViewStack implementation is to have one view slide out and when its hide effect finishes, to have second view slide in. This is demonstrated in the example below.
The implementation of this example is really very simple and you can see it below:
<?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" width="300" height="300" viewSourceURL="srcview/index.html" backgroundColor="#F0F0F0"> <fx:Declarations> <s:Move id="view1ShowEffect" xFrom="{-stack.width}" xTo="0" /> <s:Move id="view1HideEffect" xFrom="0" xTo="{-stack.width}" /> <s:Move id="view2ShowEffect" xFrom="{stack.width}" xTo="0" /> <s:Move id="view2HideEffect" xFrom="0" xTo="{stack.width}" /> </fx:Declarations> <mx:ViewStack id="stack" left="10" top="10" right="10" bottom="10"> <s:NavigatorContent id="view1" hideEffect="{view1HideEffect}" showEffect="{view1ShowEffect}"> <s:Button label="Show View 2" click="stack.selectedChild = view2" verticalCenter="0" horizontalCenter="0" /> </s:NavigatorContent> <s:NavigatorContent id="view2" hideEffect="{view2HideEffect}" showEffect="{view2ShowEffect}"> <s:Button label="Show View 1" click="stack.selectedChild = view1" verticalCenter="0" horizontalCenter="0" /> </s:NavigatorContent> </mx:ViewStack> </s:Application>
Using Flex states and transitions
Now with the states and transitions example I wanted to raise the bar a little bit. Still the goal was to slide the views but the first thing I wanted was to slide them at the same time, and second I wanted my target states to have only one view at a time. You may say this is not possible. Well not exactly. What if I introduced an additional state that was only used during the transition and it included both views for that short period of time? Check out the example below:
In the following code snippet you can see that I declared two additional states:
slideToView1State and slideToView2State. These states will actually serve when slide effects are applied. Also when you want to switch, for example to state view2State you would set the application’s currentState property to slideToView2State. When the transition from view1State to slideToView2State is finished the effectEnd event will be handled and it automatically changes the state to view2State.
Another interesting thing to note here is that the slide states are grouped in a slideStates state group and the two views don’t have to explicitly be included in slideToView1State and slideToView2State states.
<?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" width="300" height="300" viewSourceURL="http://riaspace.com/examples/ViewSlideTransitions/srcview/index.html" backgroundColor="#F0F0F0"> <s:states> <s:State name="view1State" /> <s:State name="slideToView2State" stateGroups="slideStates" /> <s:State name="view2State" /> <s:State name="slideToView1State" stateGroups="slideStates" /> </s:states> <s:transitions> <s:Transition fromState="view1State" toState="slideToView2State"> <s:Parallel effectEnd="currentState = 'view2State'"> <s:children> <s:Move id="hideView1Effect" target="{view1}" xTo="{-view1.width}" /> <s:Move id="viewShow2Effect" target="{view2}" xFrom="{view2.width}" xTo="0" /> </s:children> </s:Parallel> </s:Transition> <s:Transition fromState="view2State" toState="slideToView1State"> <s:Parallel effectEnd="currentState = 'view1State'"> <s:children> <s:Move id="showView1Effect" target="{view1}" xFrom="{-view1.width}" xTo="0" /> <s:Move id="hideView2Effect" target="{view2}" xTo="{view2.width}" /> </s:children> </s:Parallel> </s:Transition> </s:transitions> <s:Group id="view1" includeIn="view1State, slideStates" width="100%" height="100%"> <s:Button id="btnView1" label="Slide To View 2" click="currentState = 'slideToView2State'" horizontalCenter="0" verticalCenter="0" /> </s:Group> <s:Group id="view2" includeIn="view2State, slideStates" width="100%" height="100%"> <s:Button id="btnView2" label="Show View 1" click="currentState = 'slideToView1State'" horizontalCenter="0" verticalCenter="0" /> </s:Group> </s:Application>
as3viewnavigator 2.0.0 RC1 released!
I’m proud to announce a new release of the as3viewnavigator library. This new release is labeled with a 2.0.0 RC1 version number. Since the previous release the source code has been almost entirely rewritten to provide a host of new features, many bug-fixes and increased extensibility. The changes have likely also introduced some new bugs, so that is why this is an RC1 (Release Candidate 1) even though I think it is feature complete. Before it goes final I want to test it myself in battle and also have others provide input and bug reports. If you used previous versions I’m certain it will break your existing code (for your reference, the previous version is still available in github under the 1.0.0 tag.
So what is new:
- You can use
ViewNavigatorfor Flex (desktop) projects! At least until ViewNavigator from Flex Hero will not be available for desktop projects
ViewNavigatorhas become a container (based on the Sprite class for AS3 projects and theUIComponentfor Flex) now. Its default behavior in AS3 projects when added to the stage is that it takes 100% of the stage area and it auto-resizes itself. You also have an option to controlViewNavigatorwidth and height values explicitly. When using Flex you can lay it out anywhere in your MXML declaration like any other Flex component.- Default implementations of the
IViewinterface calledVieware provided for both AS3 (based onSprite) and Flex (based onSkinnableContainer) projects. - When performing actions on
ViewNavigator(like pop, push, etc.) aViewNavigatorEvent.VIEW_CHANGINGevent is dispatched. This event is cancelable so application logic can prevent the view change. Also the event has additional properties likeoldViewandnewViewwhich enable access to the instances of exchanged views. - It is now possible to add custom view transitions. This can be done by implementing the
IViewTransitioninterface and setting its implementation instance to theViewNavigatorobject’sdefaultTransitionproperty or by passing it to theViewNavigatorobject’s action functions. - View instances managed by
ViewNavigatorcan be destructed when they are no longer on the top of the stack. This can be controlled with a new property inIViewinterface nameddestructionPolicy. This property has two possible valuesautoandneverthat are also available in theViewDestructionPolicyenum class. DefaultIViewimplementations have this property set toauto.
Using it with Flex (desktop) projects:
Actually this is the feature I’m most excited about. You may wonder why this is since Flex already comes with the ViewStack component and ViewNavigator available in Flex Hero mobile projects. The reason is that the ViewStack doesn’t allow two views to be visible at the same time so this type of nice slide transition is not possible (at least the transition in which two views slide in at the same time, I will blog about this in my next post). And as I mentioned already the Flex Hero ViewNavigator is not available for desktop projects, at least not yet. Of course there is a third option, using state transitions, but it doesn’t come with an API as well thought through as the one in ViewNavigator.
Below you can see it working with Flex (right-click to access the example source code):
In the Main MXML document you can see that ViewNavigator can be treated like any other Flex component. It also has the set of properties that set up the first view and register the ViewNavigatorEvent.VIEW_CHANGING event handler. In the snippet below SampleView is registered as firstView and the viewNumber property of the first view instance is set to 1.
// 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:vn="http://ns.riaspace.com/as3viewnavigator" width="350" height="350" viewSourceURL="http://riaspace.com/examples/as3viewnavigator/flex/srcview/index.html"> <fx:Script> <![CDATA[ import com.riaspace.as3viewnavigator.demo.SampleView; import com.riaspace.as3viewnavigator.events.ViewNavigatorEvent; protected function navigator_viewChangingHandler(event:ViewNavigatorEvent):void { txtTrace.appendText( "action: " + event.action + ", oldView: " + event.oldView + " newView: " + event.newView + "\n" ); } ]]> </fx:Script> <s:VGroup left="5" top="5" right="5" bottom="5"> <vn:ViewNavigator id="navigator" firstView="{SampleView}" firstViewProps="{{viewNumber : 1}}" viewChanging="navigator_viewChangingHandler(event)" width="100%" height="70%" /> <s:Label id="lblTrace" text="Navigator events:" /> <s:TextArea id="txtTrace" width="100%" height="30%" /> </s:VGroup> </s:Application>
The SampleView MXML document extends the View class that comes with as3viewnavigator for Flex. Within the SampleView there are five buttons declared that let you play with ViewNavigator action functions. The code also declares the public viewNumber property that is set by the view that pushed the current view to the top of the stack. The value of the viewNumber property is 1 more than the viewNumber property from the previous view.
// com/riaspace/as3viewnavigator/demo/SampleView.as <?xml version="1.0" encoding="utf-8"?> <vn:View 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:vn="http://ns.riaspace.com/as3viewnavigator"> <fx:Script> <![CDATA[ import mx.utils.NameUtil; override public function toString():String { return NameUtil.createUniqueName(this); } ]]> </fx:Script> <fx:Declarations> <fx:Number id="viewNumber" /> </fx:Declarations> <s:Rect width="100%" height="100%"> <s:fill> <s:SolidColor color="#f0f0f0" /> </s:fill> </s:Rect> <s:Label id="lblViewNumber" text="{viewNumber}" fontSize="55" top="10" horizontalCenter="0" /> <s:VGroup bottom="10" horizontalCenter="0"> <s:Button id="btnPushView" label="push view" width="100" click="navigator.pushView(SampleView, {viewNumber : (viewNumber + 1)})" /> <s:Button id="btnPopView" label="pop view" width="100" click="navigator.popView()" /> <s:Button id="btnPopAll" label="pop all" width="100" click="navigator.popAll()" /> <s:Button id="btnPopToFirst" label="pop to first" width="100" click="navigator.popToFirstView()" /> <s:Button id="btnReplace" label="replace" width="100" click="navigator.replaceView(SampleView, {viewNumber : (viewNumber + 1)})" /> </s:VGroup> </vn:View>
Using it with AS3 projects:
The example below shows the AS3 version in action. You can also right-click it to access the full source code.
In this example, the ViewNavigator is instantiated and added as a child of the Main class (the Main class listing is below this paragraph). The ViewNavigator constructor receives two parameters: the class type of the first view (SampleView) to display and an Object with view properties to be set (in this case, this is my custom viewNumber property, which will be displayed in the view label). Before ViewNavigator is added as a child to the Main class it also registers a ViewNavigatorEvent.VIEW_CHANGING event handler that traces out info about ViewNavigator actions. Another thing to note here is that the ViewNavigator size is set explicitly in the layoutComponents function using setSize function. It is important to understand that in this situation ViewNavigator will not auto-size itself anymore to the size of the stage. That is why layoutComponents function is also called by stage Event.RESIZE event handler.
// Main.as package { import com.adobe.viewsource.ViewSource; import com.riaspace.as3viewnavigator.ViewNavigator; import com.riaspace.as3viewnavigator.demo.SampleView; import com.riaspace.as3viewnavigator.events.ViewNavigatorEvent; import fl.controls.TextArea; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; [SWF(width="350", height="350", frameRate="30")] public class Main extends Sprite { private var navigator:ViewNavigator; private var txtTrace:TextArea; public function Main() { // Adding source code view ViewSource.addMenuItem(this, "http://riaspace.com/examples/as3viewnavigator/as3/srcview/index.html"); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // Adding trace area txtTrace = new TextArea; // Creating instance of ViewNavigator navigator = new ViewNavigator(SampleView, {viewNumber : 1}); // Registering view navigator event handler navigator.addEventListener(ViewNavigatorEvent.VIEW_CHANGING, navigator_viewChangingHandler); // Setting components dimenstions and positions layoutComponents(); // Adding txtTrace component addChild(txtTrace); // Adding navigator to the current sprite addChild(navigator); // Adding resize handler to handle components layout stage.addEventListener(Event.RESIZE, function(event:Event):void { layoutComponents() }); } protected function layoutComponents():void { // Resizing txtTrace component txtTrace.width = stage.stageWidth; // Setting fixed height of txtTrace component txtTrace.height = 60; // Positioning txtTrace component below navigator txtTrace.y = stage.stageHeight - txtTrace.height; // Setting navigator size to be over txtTrace component navigator.setSize(stage.stageWidth, stage.stageHeight - txtTrace.height); } protected function navigator_viewChangingHandler(event:ViewNavigatorEvent):void { txtTrace.appendText( "action: " + event.action + ", oldView: " + event.oldView + " newView: " + event.newView + "\n" ); } } }
The SampleView class extends View, which is a default implementation of the IView interface. Because the View class extends Sprite you can add/remove child DisplayObjects to/from it and work with it as with a standard Sprite. Worth mentioning here is overridden function resize. Doing so allows to scale and layout child elements of the view whenever the owning ViewNavigator size changes.
// com/riaspace/as3viewnavigator/demo/SampleView.as ... override public function resize():void { for (var element:Object in _elements) { var coordinates:Object = _elements[element]; position(DisplayObject(element), coordinates.horizontalCenter, coordinates.verticalCenter); } } ...
ADC tutorial: Updating Adobe AIR applications packaged with a native installer
My tutorial about updating AIR apps packaged with a native installer was published on Adobe Developer Connection – it is available here.
It goes step-by-step through how a custom updater can be built for Windows; it also explains how a similar process could be applied for the Mac OS X platform.
This tutorial is also a good starting point to understand how my NativeApplicationUpdater library works.
as3viewnavigator – ViewNavigator for as3/flash projects
I’m currently working on an application for the BlackBerry PlayBook tablet. The API that comes with the PlayBook SDK is based on pure AS3. Of course I could use Flex Hero for the job but I wanted to try out the “native” stuff that it comes with. My impression so far is really positive and the only thing that I’ve found missing so far was the concept of Views and ViewNavigator that comes with Flex Hero for mobile devices.
That is why I took a bit of time today to create library heavily inspired by ViewNavigator from Flex Hero that I could use for my pure as3/flash projects. The library is available for download here. Also checkout the video below for the details on how to use it.
Just for the reference, to tween the view transitions I used Tweener library that is also used internally by PlayBook API.
Below is the snippet of code that implements the example from the video above, you can also download the project source from here.
package { import com.riaspace.as3viewnavigator.ViewNavigator; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.MouseEvent; import flash.text.TextFormat; import flash.text.TextFormatAlign; import qnx.ui.buttons.LabelButton; import qnx.ui.core.Container; import qnx.ui.core.ContainerAlign; import qnx.ui.core.ContainerFlow; import qnx.ui.core.SizeMode; import qnx.ui.core.Spacer; import qnx.ui.text.Label; [SWF(width="600", height="1024", backgroundColor="#FFFFFF", frameRate="30")] public class Main extends Sprite { private var navigator:ViewNavigator; private var viewNumber:int = 0; public function Main() { initializeUI(); } private function initializeUI():void { stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; // Creating instance of ViewNavigator navigator = new ViewNavigator(this); // Pushing first view to the navigator navigator.pushView(createView()); } private function createView():Container { var view:Container = new Container; view.flow = ContainerFlow.VERTICAL; view.align = ContainerAlign.MID; // Incrementing view number viewNumber++; // 20% spacer from the top view.addChild(new Spacer(20)); // Adding label with view number var numLabel:Label = new Label; numLabel.text = viewNumber.toString(); var format:TextFormat = new TextFormat; format.size = 70; format.bold = true; format.align = TextFormatAlign.CENTER; numLabel.format = format; numLabel.size = 100; numLabel.sizeMode = SizeMode.BOTH; view.addChild(numLabel); // 15% spacer between label above and buttons view.addChild(new Spacer(15)); // Adding "push view" button var btn:LabelButton = new LabelButton; btn.label = "push view"; btn.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void { navigator.pushView(createView()); }); view.addChild(btn); // Adding "pop view" button btn = new LabelButton; btn.label = "pop view"; btn.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void { navigator.popView(); }); view.addChild(btn); // Adding "pop all" button btn = new LabelButton; btn.label = "pop all"; btn.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void { navigator.popAll(); }); view.addChild(btn); // Adding "pop to first button" button btn = new LabelButton; btn.label = "pop to first"; btn.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void { navigator.popToFirstView(); }); view.addChild(btn); // Adding "replace" button btn = new LabelButton; btn.label = "replace"; btn.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void { navigator.replaceView(createView()); }); view.addChild(btn); return view; } } }





