I'm planning to break my Flex applications into different modules and need some advice regarding the loading of modules.
Currently, on load of the application, I need to add 5 modules as children to HGroups under a viewstack.
I'm using a ModuleManager to perform this and listens to the ModuleEvent to add the elements as IVisualElement under the HGroup.
Is there a way to add several modules without creating several IModuleInfo objects and multiple event listeners?
Please provide your inputs.
Here is the simplest way:
<mx:TabNavigator width="300" height="300">
<mx:ModuleLoader url="com/sample/Module1.swf"/>
<mx:ModuleLoader url="com/sample/Module2.swf"/>
<mx:ModuleLoader url="com/sample/Module3.swf"/>
</mx:TabNavigator>
Code of Module1, all others are the same:
<mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:Label text="Module 1"/>
</mx:Module>
Related
I am new to adobe flash builder and I am making a mobile flex project.
In my project so far I have a simple two page layout with buttons to go forwards and back. It's a simple hello world just to test.
I wrote an action-script that uses the camera on the phone and want to attach it to a button call so the camera opens when pressed. I have looked all over the internet but cannot find a solution for this on android and would appreciate any links for any tutorials as-well.
My button call looks like 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="Camera">
<!-- The file I want to include -->
<fx:Script source="includes/Camera.as"/>
<!-- Declarations -->
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<!-- alignment for buttons -->
<s:VGroup width="100%" height="100%" verticalAlign="middle" horizontalAlign="center">
<!-- Button that will take the user to camera -->
<s:Button label="Capture" click="button1_clickHandler(event)"/>
<!-- Button to navigate back to the main page -->
<s:Button label="Back" click="navigator.popView()" styleName="back" />
</s:VGroup>
</s:View>
This is my error:
1068: Unable to open included file: C:\Users\denis\Adobe Flash Builder
4.6\app3\src\views\includes\Camera.as.
Includes is a folder I created.
As I stated I could not find any tutorials and I am new to this so apologies for noob questions.
Where did you create the includes folder? My guess is that you created it in your app3 directory, and not as a subdirectory of src\views.
I'm currently working on an Adobe Flex Air Project, which was created with Flex 3.6! But now it should become an App for IPad, but Flash Builder can only export projects as App since Flex 4.6. So I'm trying to convert the project from Flex 3.6 to 4.6, what should be easy to do, I guess, but there are some problems with libraries and/or namespaces, which confuse me. This is how my Main-mxml starts:
<s:Application xmlns:mx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:MyComp="*"
xmlns:local="*"
xmlns:srv="generated.webservices.*"
width="1366"
applicationComplete="init()"
backgroundGradientColors="[0xffffff,0xffffff]"
borderColor="#ffffff"
color="#eaeaea"
fontSize="14"
horizontalScrollPolicy="off"
layout="absolute"
paddingBottom="0"
paddingLeft="0"
paddingRight="0"
paddingTop="0"
verticalScrollPolicy="off">
But I get the error:
`Attribute "mx" bound to namespace "http://www.w3.org/2000/xmlns/" was already specified for element "s:Application".`
But if I remove the line
`xmlns:mx="library://ns.adobe.com/flex/mx"`
then of course I can't use e.g. mx:VBox any more and would have to refactor the whole project.
I tried some test examples using Flex 4.6, e.g.
<?xml version="1.0"?>
<!-- containers\layouts\BoxSimple.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<mx:Box direction="vertical"
borderStyle="solid"
paddingTop="10"
paddingBottom="10"
paddingLeft="10"
paddingRight="10">
<mx:Button id="fname" label="Button 1"/>
<mx:Button id="lname" label="Button 2"/>
<mx:Button id="addr1" label="Button 3"/>
<mx:ComboBox id="state">
<mx:ArrayList>
<fx:String>ComboBox 1</fx:String>
</mx:ArrayList>
</mx:ComboBox>
</mx:Box>
</s:Application>
But here I get the error
`"Could not resolve <mx:Button> to a component implementation." `and more like this.
Now my question(s):
1. It's possible to use all three namespaces
`(xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark")`
Right? I saw this on several examples on the internet so I think it must work.
Do I have to reference/add external libraries to use Flex 4.6 with these 3 namespaces?
Is there an easy general way for migrating from Flex 3.6 to 4.6? Is it at all necessary to make changes or must it work in 4.6, even though developed in 3.6?
Besides, I'm relatively new to Flex, though it's not difficult I think.
Thanks in advance
Regards,
Max B
Max - to answer your question specifically it is absolutely possible to use MX components within Flex 4 apps. Your example seems to work fine with a regular flex 4.6 project. You might need to ensure you have the right library path settings.
Flex isn't difficult, but migrating between major verions can be a pain in the ass and may require a more seasoned developer. The fact is you have to know both frameworks, what are their differences and how you can fix those differences.
So Is there an easy general way for migrating? Well, ... no (or yes if you're willing to compromise, more on that later).
As for the namespaces: you can use all three of them together in one application and there's nothing special you have to do for that. That is, if you're building a traditional web app. If you're building a mobile app, some other framework libraries are used which do not inculde the components from the mx age. The reason is that Spark components or much more efficient and mobile devices just aren't as powerful as desktops yet.
Which means you'll have to convert your entire application to the Spark namespace. If your views haven't completely been separated from the business logic, you might as well rewrite it from scratch.
You can force the compiler to include the mx libraries however, even when compiling for mobile. But this will come at a performance cost.
That said, all I've said until now was on a technical level. From a UX point of view you can not expect an application that was designed for a big screen to be pleasant to use on a small one. In most of the cases these 'simple' conversions are complete failures.
I'm totally new to flex and tried to create helloWorld app unsuccessfully.
Steps:
1) Create flex project within flash builder;
2) Added <s:Label text="Hello World" x="100" y="100" /> to HelloWorld.mxml file in default package;
3) runned project with Flash Builder;
4) saw an empty flash page in browser window;
Did I miss something?
HelloWorld.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">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label text="Hello World" x="100" y="100" />
</s:Application>
P.S.
- Flash Builder 4.6;
- SDK 4.5.1;
- Other flash page do work correctly in browser (Chrome);
Ok, reposted from comment.
Did you try to open this swf in different browser?
Make sure to clear browser cache when your swf is not opened anywhere, and you
can try to delete files manually.
Sometimes it's easy to forget to save edited file, this isn't your case, is it?
Reliable approach to
see if your swf is updated or not is to Alert.show('version') or to
draw big red line across your app with graphics.
I am interested in understanding how to run a Flex-3 SWF inside a Flex-4 SWF.
My Flex-4 host app looks like this:
<?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">
<mx:SWFLoader source="SimpleFlex3App.swf" loadForCompatibility="true"/>
</s:Application>
And this is the Flex-3 app:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="400" height="400">
<mx:Script>
<![CDATA[
private function onClick():void
{
labelField.visible = true;
}
]]>
</mx:Script>
<mx:Button label="Click Me" click="onClick();" horizontalCenter="0" verticalCenter="-20"/>
<mx:Label text="Clicked" visible="false" id="labelField" horizontalCenter="0" verticalCenter="20"/>
</mx:Application>
I get a null object reference where the SWFLoader tries to set up the bridge. I assume it does not get an instance for the IMarshalSystemManager implementation.
IMarshalSystemManager(sm.getImplementation("mx.managers::IMarshalSystemManager")).addChildBridge(_swfBridge, this);
By using the SWFLoader and setting loadForCompatibility to true I was following the adobe documentation:
I must be missing out on something very simple as both, my host and hosted apps, basically don't do anything special.
Further, is it possible to do the opposite and run a Flex-4 based SWF inside a Flex-3 one? In my opinion the adobe doc does not clearly say yes or no.
Thanks.
Flex harUI provided the correct answer here at the adobe forum.
Thanks!
It is possible to do as I built an application that can load AS2 swfs into a Flex 3 SWF.
You may need to set the trustContent property to false. This will mean you swfs are in separate security domains, and communication between the two will need to happen over a shared event bridge, local connection or custom sockets.
Have a look here for more info on this http://www.pixelbox.net/2009/02/11/sub-application-communication-in-air/
I'm writing an Adobe AIR application using a ViewStack for the different application states. Is there a way to make sure that each view component is created/destroyed each time it is shown/hidden?
For instance, if I have a TextInput in a view, I want it to reset to its initial state each time I change to that view, rather than having previously entered text. Or, if I have a Timer, I want it to be destroyed when I leave the view so that it doesn't keep running when I'm in an unrelated part of the application. I know that I can manually initialize/destroy everything on the show() and hide() events, but is there an easier way?
AFAIK there is no built-in way to do this, so you'll have to do it manually by handling the show and hide events as you mention.
ViewStack does however have two methods "saveState" and "loadState" which could perhaps help you out with this. The history manager uses these methods to enable back/forward navigation. The docs don't seem to have any examples though.
ViewStacks can be the work of the devil when it comes to creation/deletion policies and managing state. We had all sorts of problems when we developed fiat ecoDrive and by about 3/4 of the way though we we're all very anti ViewStacks for the management of view state within our application.
However... a good bet would be to first set the creationPolicy to ContainerCreationPolicy.NONE. That way it's in your control as to when to create any of the panels in your ViewStack. Then i would think you would need to have some sort of logic so that as the ViewStack changes a panel it deletes or resets the one you were on.
Another viable alternative would be to use view states instead. Have a base state which acts as the main container and then a simple state for each of your sections. That way when you switch to a new state, the old state gets removed in reverse order to the way it was created. You do have to be disciplined with states though as they can end up getting really complex and messy when they start becoming nested. If you keep it simple it may work as you require.
In MXML 2009, you can use itemDestructionPolicy="auto" to destroy a component after use it. If you use this property in the first view component with two states (init, logged), you can destroy and reinitialize all child view components. Example :
<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>
Both answers are correct -- there doesn't seem to be any built-in way to do it. I solved the problem by creating a "wrapper" component for my view component. It creates a new view component each time the view is shown. This isn't ideal, but fits my requirements nicely, and required few changes to my application structure.
<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>
Build your "views" as separate Modules, and then use the ViewStack to switch between them. You could then write a function to destroy the unused module(s) (check each module against the selectedChild property) when the ViewStack's "change" event is fired.
2ยข
I am using different states for my different views. On each state change i add and remove components.
This causes the add and remove events of UIComponent fire which allows me to initialize and cleanup my components each time they are added.
This is the idea...
<mx:states>
<mx:State name="state1">
<mx:AddChild>
<mx:SomeUIComponent id="myComp" add="myComp.initialize()" remove="myComp.cleanup()"/>
</mx:AddChild>
</mx:State>
</mx:states>