Loading css when your application starts up

In Flex 2.0.1, Flex introduced a feature enabling runtime css. This meant that your application could load a different stylesheet at runtime using the method StyleManager.loadStyleDeclaration(url). This allows your Application’s swf to be much smaller if you had multiple stylesheets for one Application that may or may not be used. Unfortunately, you cannot load the css directly. Instead, you would need to compile the css using the Flex compiler. The compilation of a css file will create a swf file that can be specified as an argument to loadStyleDeclarations method. Here is the description of this method from the Flex livedocs:

public static function loadStyleDeclarations(url:String, update:Boolean = true, trustContent:Boolean = false, applicationDomain:ApplicationDomain = null, securityDomain:SecurityDomain = null):IEventDispatcher Loads a style SWF.

Parameters


url:String — Location of the style SWF.


update:Boolean (default = true) — Set to true to force an immediate update of the styles. Set to false to avoid an immediate update of the styles in the application. This parameter is optional and defaults to true For more information about this parameter, see the description in the setStyleDeclaration() method.


trustContent:Boolean (default = false) — Obsolete, no longer used. This parameter is optional and defaults to false.


applicationDomain:ApplicationDomain (default = null) — The ApplicationDomain passed to the load() method of the IModuleInfo that loads the style SWF. This parameter is optional and defaults to null.


securityDomain:SecurityDomain(default = null) — The SecurityDomain passed to the load() method of the IModuleInfo that loads the style SWF. This parameter is optional and defaults to null.

Returns


IEventDispatcher — An IEventDispatcher implementation that supports StyleEvent.PROGRESS, StyleEvent.COMPLETE, and StyleEvent.ERROR.

So, how can you load css at runtime and not create any of the components in your application until the styles were loaded? You want to be sure that your components don’t show up on screen with default styles for a brief amount of time while the css is being loaded. There are probably a few ways to do this, but, here is one that I found that works.

1. Call StyleManager.loadStyleDeclarations(url) in the preinitialize handler for your <mx:Application>

2. Make sure that your <mx:Application> has a creationPolicy=”none”.

3. When, the StyleEvent.COMPLETE event is triggered after the call to loadStyleDeclarations, then, you can call createComponentsFromDescriptors(). This method will create all of the children of the container that it is called on.

Here is the code in the Application:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; width=”100%” height=”100%”
preinitialize=”changeTheme()” creationPolicy=”none”>
<mx:Script>
<![CDATA[
import mx.styles.StyleManager;
import mx.events.StyleEvent;private function changeTheme(): void
{
var myevent:IEventDispatcher = StyleManager.loadStyleDeclarations(“Ice2.swf”);
myevent.addEventListener(StyleEvent.COMPLETE, createComponents);
}

private function createComponents(event:StyleEvent): void
{
createComponentsFromDescriptors();
}
]]>

</mx:Script>

<mx:Panel id=”main” width=”100%” height=”100%”>
<mx:HBox>
<mx:VBox>
<mx:Label text=”comments:” />
<mx:TextArea width=”200″ height=”150″ />
<mx:Button label=”submit” />
</mx:VBox>
<mx:DateChooser />
</mx:HBox>

</mx:Panel>
</mx:Application>

Demo: Icetheme.swf, Ice2.swf

Source: Icetheme.mxml, Ice2.css

7 responses

  1. Thats a great tip. CSS invalidation is, from what I understand, a pretty heavy operation since all the components have to be re-laid out etc, so this may save a few processor cycles. Thanks

  2. There’s actually a cleaner way to do this. You can override the initialized() setter to prevent the preloader from disappearing until your style SWF has been loaded.

    I wrote up the details in a blog post a week or two ago here:
    http://userflex.wordpress.com/2008/02/07/preload-runtime-styles/

    Still, nice solution! :)

  3. Thanks for sharing Nick!

  4. but i think only preventing initialized from beeing set, wont prevent all components from beeing layed out twice.

  5. Wow, I spent all my night trying to figure this out, going back and forth and trying a bunch of solutions I found on Google… now it’s 9:47 AM and it finally works…

    I had weird results with a lot of components not initializing properly.

    Thanks a lot ! Too bad Adobe isn’t documenting this.

  6. By the way,
    I’ve tried Nicks solution as well but with no results.

  7. so wat is the work around..I am still facing the problem..Any help?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: