Preloader Base Class

UPDATE: Thanks to the suggestions of Casey, I’ve updated the base class to use events from the loaderInfo instead of checking each frame, as well as using the frame label as the class name (which I believe is the idiom that Flex’s [Frame] metadata follows).

I reread the preloader post I made earlier today and it occurred to me I should make this an actual re-usable class. So, I did. Here’s the Preloader base class:

Usage is very straightforward. I made everything protected for easy sub-classing, but you shouldn’t have to override the event handlers, onProgress(), onComplete and onRemovePreloader().

As I discussed in my earlier article on the subject, you have to include a compiler argument to force your main application class to be loaded on a secondary frame. You do this using the -frame compiler argument like so: -frame frameLabel fullyQualifiedClassName.

To customize the preloader animation, override addPreloader(), updatePreloader() and removePreloader().

To create your main application class you can either pass the application class’s name into the constructor, e.g. super("com.mycompany.myapp.Application");, or you can use the class’s name as the frame label in the compiler argument, e.g. -frame com.mycompany.myapp.Application com.mycompany.myapp.Application. If you need to do something more specialized than just constructing your class and adding it to the stage, you can override createApplication().

Here’s an example of a preloader that displays progress as a percent in the top-left corner of the screen:

Tags:

  • http://blog.flashchemist.com/ Vipin

    Troy,
    Do you really have to extend MovieClip for the base class? Sprite will not work?

    Vipin

  • troygilbert

    You need to extend from MovieClip because you have to control the
    frame playback with stop(), nextFrame(), framesLoaded and totalFrames.

  • http://www.caseyk.com Casey

    This is glorious, thanks. One tip– the Application class can be conveniently be stored in the currentLabel property of the timeline if you use the following compiler command:

    -frame ExampleApp ExampleApp

    This is because the second argument is frame label, not frame number. This used to work intrinsically when using [Frame(factoryClass="Preloader")] (the compiler is smart enough to use this class name as the frame label). Using this method you don't need to store the app class name in a constant or pass it from extensions, and since the preloader is already dependent on compiler arguments, it makes sense. You'd use it like this:

    var ClassReference:Class = getDefinitionByName(this.currentLabel) as Class;

    Also it might be a little more elegant to listen to the root.loaderInfo object's events, like so:

    this.root.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onRootLoaderInfoProgress);
    this.root.loaderInfo.addEventListener(Event.COMPLETE, onRootLoaderInfoComplete);

    Again, great work, thanks for sharing. [Frame(factoryClass="Preloader")] was not working for my Preloader class extensions, this solves the issue nicely!

    –C

  • Casey

    Whoops, I meant the FIRST argument is frame label, but regardless, both should be identical

    -frame ExampleApp ExampleApp

  • troygilbert

    I like that a lot. I'll definitely update the post to use the frame label technique; one less dependency is what I'm look for.

    In regards to the progress/complete events: I agree, definitely more elegant. Originally, I checked each frame because I was also updating a loading animation. Still a good idea, but for the purpose of this example and I think listening for the events is the better approach. I'll make updates for that as well.

  • troygilbert

    I like that a lot. I'll definitely update the post to use the frame label technique; one less dependency is what I'm look for.

    In regards to the progress/complete events: I agree, definitely more elegant. Originally, I checked each frame because I was also updating a loading animation. Still a good idea, but for the purpose of this example and I think listening for the events is the better approach. I'll make updates for that as well.

  • Denis

    Hello first thanks for this,

    but i have a little Problem with the implementation of this code in a project who used the flex sdk.

    It don't works at all, i use a trace in the onProgress and onComplete function but they don't feed me any information.

    Thanks.

    Sorry for my english.
    Denis

  • http://twitter.com/nordhagen Øyvind Nordhagen

    Just stumbled upon your posts while trying to work out how to develop an app with a preloader in IntelliJ. Seems that the concept of setting up classes as separate compiling applications is foreign to IDEA, so this solution seems very tempting.

    Having one issue though: adding -frame 2 Main to the Flex Compiler Settings for the module in Project Structure and the compiling gives me the following error:

    ambiguous argument list; unable to determine where 'frames.frame' parameters end, and default 'file-specs' parameters begin. Use '–' to terminate the parameter list, or perhaps use the '-frames.frame=val[,val]+' syntax instead.

    Then i tried removing the hyphen at the beginning, but then all I get is:

    unable to open 'Main'

    Main is a class in the same package as Preloader, so I really don't get this…

    EDIT: I should mention that I am using SDK 4.1.0. Could that have something to do with it?

  • Dimmdesign

    hi, ex

  • Dimitris

    Hi, excellent class. works really well, except when I try to dispatch an Event from my main class it nevers get caught…, bubbling were true. any thoughts?