Runtime styles are great. They allow you to dynamically change the look-and-feel of your application, and they reduce the size of your deployed SWF.
But when you load your style SWF at startup, there is a potential delay between when your application is displayed and your runtime styles are applied.
Why does this matter? Because in that minute fraction of time your application is visible before your runtime styles are applied, the default Flex styles are visible. The result is a not-so-subtle flicker as your styles change.
Fortunately, there is an easy solution.
It turns out you can prevent the Flex preloader from disappearing until your runtime styles have been loaded. If you override the initialized setter in your main MXML file, the preloader will not disappear until you call super.initialized = true.
Here’s the sample code:
|
<?xml version=”1.0″ encoding=”utf-8″?> <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” preinitialize=”onPreinitialize (event)”> <mx:Script> <![CDATA[ import mx.events.FlexEvent; import mx.events.StyleEvent; private function onPreinitialize (event : FlexEvent) : void { var eventDispatcher : IEventDispatcher = StyleManager.loadStyleDeclarations ("my_style.swf"); eventDispatcher.addEventListener (StyleEvent.COMPLETE, onStyleComplete); eventDispatcher.addEventListener (StyleEvent.ERROR, onStyleComplete); } private function onStyleComplete (event : StyleEvent) : void { super.initialized = true; } override public function set initialized (value : Boolean) : void { // wait until the style swf is done loading! } ]]> </mx:Script> </mx:Application> |

16 comments
Comments feed for this article
March 4, 2008 at 5:34 am
burnhh
thx for the great tutorial. is there a possibility to avoid the “minute fraction of time your application is visible before your runtime styles are applied” when loading a different style sheet at runtime and not at startup? whenever I use StyleManager.loadStyleDeclarations it switches back to the default CSS for a glimpse of the eye. I’m a bit stuck with that one.
thx, burn
March 4, 2008 at 9:05 am
Nick Schneble
Yeah, that one is tricky since your application is already visible.
Are you setting the update parameter in StyleManager.loadStyleDeclarations() to true?
If you are switching from one runtime-loaded style to another, you can try calling StyleManager.unloadStyleDeclarations() with update set to false for your existing style SWF, and then calling StyleManager.loadStyleDeclarations() with update set to true for your new style SWF.
March 4, 2008 at 10:40 pm
burnhh
thx for the reply, i’ll try that.
March 4, 2008 at 11:43 pm
burnhh
hmm, that doesn’t seem to work =( maybe you’ve got an idea what’s wrong with that. here’s my quite simple test app. the three style sheets only contain the following code (with changed background gradient colors, of course). you need three different css files compiled to styles1.swf, styles2.swf and styles3.swf
regards, burn
// —– sample css file —–
Application
{
backgroundGradientColors: #FF0000, #FFFFFF;
}
// —– the App —–
March 4, 2008 at 11:46 pm
burnhh
ok, my code was apparently ditched. so here’s the source
http://www.konzentrik.de/bk/CssTest.zip
burn
March 5, 2008 at 8:59 am
Nick Schneble
Burn,
I took a look at your code and I think I’ve figured out the problem.
This is actually something different than the “minute fraction of time your application is visible before your runtime styles are applied” mentioned in my post.
The flicker you’re seeing seems to be a unique issue with the system chrome of an AIR application when a runtime style is loaded.
I modified your code to prevent this by setting showStatusBar on the WindowedApplication to false, and by creating a root-level Canvas container that fills the entire application space.
Then, instead of changing the background color of the WindowedApplication, I simply set it to change the background color of the Canvas. Voilà! No flicker!
If you want to use a background gradient instead of a solid background color in this example, check out my post on creating a GradientCanvas container.
March 5, 2008 at 10:36 pm
burnhh
great, thx man! i’ll keep folowing you blog =)
burn
March 6, 2008 at 8:19 am
Nick Schneble
No problem!
December 15, 2008 at 10:18 am
rajeshbhadra
If I load a skin swf file for a particular component using StyleManager.loadStyleDeclaration(path,true), it loads up the swf file and applies the skin assets(up,over and down states) to a particular component. But at the same time it also breaks up the system font color. The textarea’s font color changes to white and also the text color of the button changes to white. Can you help ? I am using flex builder 3 and sdk version is 3.0.0 along with Flash Player version 9.0.124.
December 29, 2008 at 11:48 pm
terencechu
hi nick
i try to override the initialized setter in my main MXML file and then call
super.initialized = true.
but seem can’t work.could you give me the sample code?
January 7, 2009 at 11:34 am
Nick Schneble
@rajeshbhadra
Can you post the CSS for your style SWF?
When you load a new style declaration it will override any previously loaded styles, so it’s likely that something in your style SWF is setting those colors to white.
January 7, 2009 at 11:48 am
Nick Schneble
@terencechu
Sure thing, I’ve added sample code to the post.
January 7, 2009 at 7:34 pm
terencechu
thanks for the sample code.my code is work fine now.:)
January 15, 2009 at 4:00 pm
How to Restrict Your Flex App By Domain « Miscellanea
[...] You can check the current domain on preinitialize, for example, and simply never display the UI for a restricted domain (more on that here). [...]
February 19, 2009 at 10:06 am
LyraSpace » Blog Archive » Customise your Flex preloader the easy way
[...] The FlexEvent.INIT_COMPLETE event is triggered after your SWF has completely loaded AND your Application has initialised. This is important because by default the COMPLETE event is called after the SWF has loaded and the initialisation is handled while displaying your Application’s guts. I tend to use runtime Flex styles so I need these loaded before displaying my Application. A great article on this is available here. [...]
March 15, 2009 at 11:10 pm
Solution Hacker - Flex Startup Sequence
[...] Dynamic loading a new custom theme without fraction seconds delay [...]