What I'm trying to do: allow a user to be able to select a color palette for a custom component by selecting from a drop down menu with a variety of icons.
I have the drop down menu part down, but I'm trying to understand how to best handle the various styles in my code. Ideally I would have liked to be able to load styles at run time, but I don't see a major advantage with this so I'm now thinking about compiling in all styles. Still, I can't seem to find a decent way to structure the code. Hacking it seems pretty easy / fast, but there's got a better way than having a big fat array of values which can be indexed via some index associated with each icon - yuck!
Would love to hear your thoughts or see any pointers to obvious ways to handle this.
thank you!
fred
I'd define a set of style names in CSS, then you can use a collection of style names to provide values for your style selector control, like so:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Style>
.style1{color:red;}
.style2{color:green;}
.style3{color:blue;}
</mx:Style>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
public static const styleNames:ArrayCollection =
new ArrayCollection(['style1', 'style2', 'style3']);
]]>
</mx:Script>
<mx:ComboBox
id="styleCombo"
styleName="{styleCombo.value}"
dataProvider="{styleNames}"
/>
</mx:Application>
The optimal way to achieve this is to compile several CSS+Swf(assets) files and then loading them at runtime according to what the user selected.
This is by far the best practice out there, I used it for large applications and small applications and it stands tall above every other solution I could think of.
good luck
Related
I have created an item renderer spark list in flex , but i want to call a function on addition of new row in list and not afterwards. I am getting a data object in rendered list in it i am getting the type of data to be displayed in list ie. either text or image. So on addition of new data in list i want a function to be called up in rendered list that checks the type of data received and then it will either create and add an image element or a text element. So the main problem is how i get a function called on addition of data. I have tried events like datachange and added but they keep on calling the function over and over again when we scroll the list but i want the function to be called once only on addition of data and not after wards. Below is the renderer list code , maybe you will get a better idea of what i am trying to do:
<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" dataChange="test_add()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
public function test_add() : void {
Alert.show("type="+data.msg_type);
if(data.msg_type=="text"){
//code to create and add new text element to list_row//
}
if(data.msg_type=="image"){
//code to create and add new image element to list_row//
}
}
]]>
</fx:Script>
<s:Group id="list_row" width="100%" verticalAlign="middle" verticalCenter="0">
</s:Group>
</s:ItemRenderer>
Any help will be highly appreciated.
Thanks
As far as I can tell from the code you show, the easiest solution to your problem would be to work with two separate ItemRenderers: one that renders text and the other that renders images. You can do this using the SkinnableDataContainer#itemRendererFunction property instead of itemRenderer.
The List with the new property:
<s:List id="myList" dataProvider="{dp}"
itemRendererFunction="getItemRenderer" />
The function that returns a factory for the right ItemRenderer.
private function getItemRenderer(item:Object):IFactory {
if (item.msg_type == "text")
return new ClassFactory(MyTextItemRenderer);
if (item.msg_type == "image")
return new ClassFactory(MyImageItemRenderer);
}
In these two different ItemRenderers you can then display your data as you wish.
Edit: why it's OK that the dataChange event fires every time you scroll.
There is in fact nothing wrong with your approach as you describe it, although I would argue that the itemRendererFunction approach allows for better separation of concerns. I could tell you that you can turn the unwanted behavior off, simply by setting the List#useVirtualLayout property to false.
<s:List id="myList" dataProvider="{dp}"
itemRenderer="myItemRenderer" useVirtualLayout="false" />
Though this will do what you ask for (i.e. create the ItemRenderers only once), that would not be good advice. There is a good reason this property is set to true by default.
When virtual layout is used, item renderers are created only as they are needed, i.e. when they come into view and need to be displayed to the user. This allows you to load thousands of items without performance loss.
Let's say you load 1000 value objects: that doesn't take up much memory or CPU. But now you want to render them. If you don't use virtual layout an item renderer will be created for all of them up front, which means thousands of graphic elements and thousands of event listeners (how many exactly depends on your setup). Now that is going to hurt performance on a slow computer.
If you do use virtual layout only - say - 10 item renderers will be created at once. If the user scrolls down, the next 10 will be created and the ones that just disappeared from the view are removed and eventually garbage collected. So you see: what you may have perceived as something that was bad for performance at first, is actually a very good thing.
So I would advise you not to do what I just told you. Unless perhaps you would have a situation where you knew there would never be more than a very limited number of items in your List. Then you may consider not using virtual layout.
Would anyone be able to point out some good tutorials on creating applications in flex that are don't have UI's?
Actually, it looks like all I really need to know is how to call a function upon initialization of the flash object. I tried the creationComplete attribute, but it doesn't work in browser.
Well, I'm not sure what made it work finally, but I ended up copying and pasting this code from some website (sorry, i don't remember the site):
<?xml version="1.0" encoding="utf-8"?>
<!-- wrapper/CheckExternalInterface.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"
creationComplete="initApp()">
</s:Application>
And that ended up working! thanks anyway.
If you're intent is to connect JavaScript to a Java Server, why not use XMLHTTPRequest? IT is the basis of every AJAX style RIA application. The data format you pass back and forth can either be JSON or XML. It doesn't have to be binary.
Second, you don't need Flex for this. The Sockets APIs in ActionScript and are part of the Flash Player. You can use them without any dependencies to the Flex Framework.
We are migrating our Flex-3.2 application to Flex 4.1, mainly to take advantage of the new text flow/engine features. In a first step we decided to go with compiling for MX-only and in Flex-3-compatibility mode.
Thanks to some helpful resources (
http://www.adobe.com/devnet/flex/articles/flexbuilder3_to_flashbuilder4.html
Any Flex 4 migration experience?
http://www.adobe.com/devnet/flex/articles/flex3and4_differences_02.html
) I am able to compile our application.
But I find myself surprised about the amount of runtime differences ranging from the problem that I cannot cast ResultEvent.currentTarget to HTTPService ( which apparently was introduced in 3.5 ) to many layout problems to differences in event dispatching ( e.g. one of our legacy components listens to the add event which it just doesn't seem to get anymore ).
It seems there is very little documentation on this. I'd like to find a list with detailed changes so that we don't have to rely on QA to stumble across hopefully all issues.
This documents lists some, but doesn't seem exhaustive.
Does someone have a better list of documented changes?
Thanks
Stefan
PS. List of concrete examples I have found so far:
1) In Flex 4 the add event is not fired:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx" layout="absolute" minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
private function notFired():void
{
trace("ADDED");
}
private function fired():void
{
trace("COMPLETE");
}
]]>
</fx:Script>
<mx:TextArea add="notFired();" creationComplete="fired();"/>
</mx:Application>
Now do the same in Flex 3 and you'll see both events fire.
Apparently, this is a bug. Might be possible to work around this but certainly decreases my level or trust substantially.
2) Dialogs/popups show all content mirrored.
A bug as well. Easy to work around, but how could something that obvious slip?
3) Problems with injected "Ôª" chars.
See post here.
Let's see some of your doubts...
1) add never was a reliable event since flash player 9 release. It's a common bug. Try to create a movieclip out of displaylist and add a child in it that have the Event.ADDED listener. In some situations (don't know exactly what situation) it doesn't work (Adobe Fail). But, instead the "add" flex event, use the "added" or "addedToStage" once you want to detect if it's already in your applications display list.
2) Fail. Check the layout manager source-code of the framework.
3) I've never seen this. (Even in compatibility mode). Can you show an example? Did you check if the application encoding is the same you're using on your strings? Maybe the string table could be doing some confusion due to the characters encodings (or maybe your editor). Try other editors and verify the code file contents on a linux shell with SED. With a find and a sed you can fix it easily.
I have used Flash to make skins, which I import and apply to Flex components.
But how can I create a component in Flash, with properties and methods. And make it able to be added to the displayList in a Flex app?
I installed the Flex component kit for flash. Created my component in flash (it extends MovieClip). Did Command->Convert to flex Component, did File->Published, which gave me a .swc, dropped the .sec file into my Flex project. Now when I create a new var the class "FlashFlexComponentTest" pops up in the new class hint box, so flex sees it. But afterwards I get the error:
Type was not found or was not a
compile-time constant: FlashFlexComponentTest
I feel like I must be missing a step?
Thanks!
UPDATE
I added the .swc via project build path -> add SWC.
I no longer have a compile-time error but I am getting a runtime error:
Type Coercion failed: cannot convert FlashFlexClassTest#9089129 to mx.core.IUIComponent
The base class for all flex components, UIComponent, allows you to add Sprites that don't implement the IUIComponent interface.
An example :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="init();">
<mx:Script>
<![CDATA[
private function init():void
{
var component:FlashFlexClassTest = new FlashFlexClassTest();
container.addChild(component);
}
]]>
</mx:Script>
<mx:UIComponent id="container" width="100%" height="100%"/>
</mx:Application>
There's a good video tutorial on this at Linda.com by David something. I did a lot of this a year or so ago, and that was the best resource I found. Doesn't cover absolutely every possible angle, but does a great job of covering what you need to know.
I'm guessing there's just some small linkage detail that you're missing. The tutorial should get you straight, if that's the case. It was worth the $20, or whatever, for a monthly subscription for me.
Sorry, that's the best I can do... haven't built Flex components in Flash since last year.
basically there are step what need to do:
open Flash
drag a component you need to stage
right click on it in Library > Export to SWC
put this SWC in your Flash Builder libs folder
There is explanation by Jesse Warden http://jessewarden.com/2011/06/integrating-flash-components-with-flex-revisited.html
Cheers!
Is there a way to hide the preloader. One idea I have is to make a new one that is empty, but surely there must exist an easier way to do it.
It might sound like a dumb idea but in some situations it can be nice to just hide the preloader. Especially if it doesn't require a lot of work.
Add usePreloader="false" to your mx:Application tag:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
usePreloader="false">