company-logo

Custom Flex 3 Lightweight Preloader with source code

Preloader

Here we have a demonstration to an age old problem in Flash (inherited in Flex) – the Preloader. I think that the Flex community has long ago grown bored with the default preloader, which I am very thankful to Adobe engineers for providing us in the first place. It’s just that we keep seeing it over and over and over…

Another important thing that the default preloader naturally doesn’t provide is some branding while the user is waiting for the loading to complete.

There are some great examples out there like Ted’s and the one that I’m using as a base for this demonstration from Andrew.

Andrew’s example allows us to have a lightweight preloader base that we can extend and solve the following problems that I think every preloader should:

- What is the status of loading – both numerically and graphically

- Some branding to show what are we waiting for that would involve some imagery, like a logo

- Possibility of actually making the preloader entertaining enough to keep the users attention

Problem in Flex more so than in Flash is keeping the preloader lightweight. So we have to achieve the visual appeal, animation, some basic text rendering without all the convenient native Flex components that would make the delay before seeing the preloader too long. So we have to keep it simple. Kudos to Andrew for publishing a great way to do this.

I would like to point out a couple things:

1. So we want to show the percentage loaded, right? Well, the Label component just won’t work out. Label comes with following inheritance:

Label -> UIComponent -> FlexSprite -> Sprite -> DisplayObjectContainer -> InteractiveObject DisplayObject -> EventDispatcher -> Object

That is a good part of the Flex framework that we want to avoid for the preloader. Instead, because we just want to render the text, we can use the TextField object which comes with following inheritance:

TextField -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object

And another thing is that we want to avoid any custom fonts in the preloader because that will surely blow it up.

2. Any imagery that we want to show up should naturally be in the single digit kilobytes to begin with. Photoshop offers a lot of ways to optimize the size of the image.

Than again, we don’t want to use the convenient Image component because it comes with the following inheritance:

Image -> SWFLoader -> UIComponent -> FlexSprite -> Sprite -> DisplayObjectContainer -> InteractiveObject -> DisplayObject -> EventDispatcher -> Object

Instead, we can fill up a DisplayObject that comes with following inheritance:

DisplayObject -> EventDispatcher -> Object

To do this you:

- embed your small image in the preloder like so:

[Embed("Assets/Pathfinder_Logo_Blue.png") ]
[Bindable] public var Logo:Class;

- pass the Logo class to DisplayObject and add it to stage, like so:

var b:DisplayObject=new Logo();
addChild(b);

and then set it’s size and position parameters.

We only want to show the image pixel, so this will do. We can still make our logo DisplayObject available throughout the whole preloader class so we can play with it a little, like making it follow the progress bar by changing it’s X parameter.

The rest you can pick up from the source code, available here.

You can see the example here.

Again, thanks to Andrew, Ted and Adobe Flex Team.

Related Services: Flex, Flash and Air, Custom Software Development

  1. roamer Reply

    Very nice !!Thank you !

  2. Sander Reply

    Is it possible to load a swf file for preloading and call a function in that swf.

    For instance, I would like to use a kind of speedometer for preloading. I’ve created a swf that has a ‘setPercentageLoaded(percentage)’ function in the first frame of the movieclip. This function rotates the dial of the speedometer based on the percentage loaded.

    I’ve been trying to accomplish this, but embedding swf files causes the function to be unreachable.

    Any help would me most appreciated.

    Regards,

    Sander

  3. Sasha Dzeletovic Reply

    Hi Sander,
    To the best of my knowledge it is not possible call a method within a swf file while it’s loading because it doesn’t exist yet. Having the preloader in the swf that you are trying to load defies the purpose because your swf would need to load before showing your the preloader.

    You do not need to do that at all because there are other ways around this.
    In my experience, it is best to keep the preloader extracted so you can call on it anytime for anything and reuse it.

    Your scenario could look something like this:
    - You have a base file. It’s a default MXML.
    - In your project, you have a component that will act as your preloader and is loaded together with your application.
    - You have an external swf that you want to load after your app has loaded.

    From that starting point we go to code in base file (imports not included):

    //loader that will track the progress
    private var myLoader:Loader;
    //your custom preloader component
    public var myPreloader:Speedometer;

    //create your preloader and call the loading of the external swf file
    private function getSwf():void
    {
    //create your new preloader component
    myPreloader = new Speedometer();
    //position it where ever you want and set any other parameters you want
    myPreloader.x = 100;
    myPreloader.y = 100;
    //add your preloader to stage
    addChild(myPreloader)

    //create your loader
    myLoader = new Loader();
    //create a new URLRequest to use as with Loader
    var mySwfURL:URLRequest = new URLRequest(“URL_of_my_swf.swf”);
    //attach a listener to loader so you can track the progress using it
    myLoader.addEventListener(ProgressEvent.PROGRESS, trackProgress);
    //start loading
    myLoader.load(mySwfURL);
    }

    //trackProgress is attached to the listener and is being passed “progress” parameters in event parameter
    private function trackProgress(event:ProgressEvent):void
    {
    //this is where you can pass the progress to your custom preloader
    myPreloader.setPercentageLoaded(event.bytesLoaded / event.bytesTotal * 100 );
    //if the swf has loaded, remove your listener and custom preloader from the stage
    if(event.bytesLoaded == event.bytesTotal)
    {
    myLoader.removeEventListener(ProgressEvent.PROGRESS, trackProgress);
    removeChild(myPreloader)
    }
    }

  4. kalluru Reply

    Hi,
    Thanks for proving such a beatiful component code,I am trying to use this preloader for AIR application its not working and its perfectly working for Web app’s.Pls clarify me that preloder concept will work for AIr,if possible provide some sample.

    Thanks & Regards
    Kalluru

  5. Darina Reply

    Hi Sasha,

    Thank you for sharing your solution with us!

    Can we use your preloader with our logo in our applications? Are there any licenses or restrictions?

  6. Sasha Dzeletovic Reply

    Hi Darina,
    Thanks! You can use this preloader in your applications without any restrictions whatsoever. Also feel free to change it, extend it or whatever else that comes to your mind. Pathfinder logo is copyrighted though :)

  7. Sasha Dzeletovic Reply

    Thanks Kalluru,
    I haven’t tried this in AIR but right of the top of my mind I would think something similar could work. Main difference that I foresee is that in AIR we are not loading but mostly initializing. I will get to it when time permits and update to this post on that topic.

    Cheers!

  8. David Testas Reply

    Hi Sasha,

    thanks for you sharing this custom prloader.
    Is it possible to eliminate the short blink
    before the preloader of the standard flex
    page.
    It’s only 1 second I know, but I say better gone then there.

    cheers, David

  9. MechanisM Reply

    Very good preloader!! Thnxx for sharing!!

  10. Siva Reply

    Excellent Preloader :) with great color combination also.

  11. Warren Reply

    I do like the preloader and the branding.

    I am curious about how it compares in speed (like load time) with the default preloader. I don’t want to introduce anything that is going make things slower but I’m guessing this one is lighter than the stock one and should go faster?

    I’d also like to use this in an external class library. How can the constructor be modified to accept different images rather than embed an default? This way it could be used for many different brands. preloader=”com.pathf.preloaders.PathfinderCustomPreloader(‘assets/myimage.png’)”

    Thanks!

  12. Fizzy Reply

    Hi Sasha,

    This is great. Thanks for sharing. Is there a way to set a minimum time for this preloader? I’ve seen the following used elsewhere.

    MINIMUM_DISPLAY_TIME=2000;

    Would this work in your preloader. If so, where should it be added?

    Thanks!

  13. Antonio Reply

    i implemented thi preloader for flex , quite good looking ,Took source code from this link

    http://askmeflash.com/article_m.php?p=article&id=7

  14. Gustavo Pereira Reply

    This is really cool and very useful. Thanks Sasha!

  15. Phu Reply

    Great! Thank you very much.

  16. Klaus Reply

    Hello Sasha,

    thanks for this great preloader

    I have a question though.

    I have an application swf and a css swf, and i need them to be separated.

    do you know how make the bar show the percentage of both files?

  17. Klaus Reply

    Hi again after a litle bit of study on how the style manager works y understood that i could load styles from the preloader into the aplication.

    heres is the code that needed to change to make it happen.

    there are a few problems with the bar because it still downloads the full aplication before it starts downloading the style so the bar is full before itshould be but you can play with this making and drawing 2 bars or using 2 colors or 2 diferent alphas
    you choose.

    ////

    protected var _IsStyleComplete:Boolean = false;
    protected var _styleBytesLoaded:uint = 0;
    protected var _styleBytesExpected:uint = 1;
    virtual public function set preloader(value:Sprite):void {
    _preloader = value;
    value.addEventListener(ProgressEvent.PROGRESS, progressHandler);
    value.addEventListener(FlexEvent.INIT_PROGRESS, initProgressHandler);
    value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler);
    var eventDispatcher:IEventDispatcher = StyleManager.loadStyleDeclarations(“main.swf”);
    eventDispatcher.addEventListener(StyleEvent.COMPLETE, completeStyleHandler);
    eventDispatcher.addEventListener(StyleEvent.PROGRESS, progressStyleHandler);
    }
    virtual protected function progressHandler(event:ProgressEvent):void {
    _bytesLoaded = event.bytesLoaded;
    _bytesExpected = event.bytesTotal;
    _fractionLoaded = (Number(_bytesLoaded) + Number(_styleBytesLoaded)) / (Number(_bytesExpected) + Number(_styleBytesExpected));
    draw();
    }
    virtual protected function progressStyleHandler(event:StyleEvent):void {
    _styleBytesLoaded = event.bytesLoaded;
    _styleBytesExpected = event.bytesTotal;
    _fractionLoaded = (Number(_bytesLoaded) + Number(_styleBytesLoaded)) / (Number(_bytesExpected) + Number(_styleBytesExpected));
    draw();
    }
    virtual protected function completeStyleHandler(event:Event):void {
    _IsStyleComplete = true;
    }
    virtual protected function timerHandler(event:Event):void {
    if (_IsInitComplete && _IsStyleComplete) {
    _timer.stop();
    dispatchEvent(new Event(Event.COMPLETE));
    } else
    draw();
    }
    ////

  18. Rajiv Totlani Reply

    Nice…for those who do want something more customized with there logo etc, the challenge lies not in the 1 line of Flex code, but more in the Flash graphic which the flex preloader will use.

    For those who want something good and affordable, there are some websites out there that sell Flex preloades for under $10 like http://www.flexdownloads.com. I kind of like there preloaders better than the default one :)

  19. Pingback: The Blogagic Custom Flex Preloader | Blogagic

  20. Paul Reply

    The source link doesn’t work anymore can you provide a new link?

    • Sasha Dzeletovic Reply

      Paul, I’m sorry about that. We moved new domain recently and I didn’t put in all the redirects in.

      Link is still the same but the redirect points to new location now.

Leave a Reply

*

captcha *