Making a Cooler Preloader in Flex: Part 1 of 3

Making a Cooler Preloader in Flex: Part 1 of 3

Preloader Preview

Preface

Preloaders in Flex are not like preloaders in Flash. Gone are the days of the 1 liner:

if ( _framesloaded < _totalframes ) gotoAndPlay ( 1 );

We now have base classes and setter properties. While you may have to write a class and then set that class on your Application’s preloader property, it’s really pretty easy once you do it more than once. This tutorial will show you how to build a preloader in Flex using a Flash built animation.

Introduction

Flex’ built in preloader is pretty sweet. It auto-adjusts for your application’s color to stand out, it handles all aspects of preloading. This includes remote shared libraries, fonts, and even deferred classes used in modules. Finally, it deals with the initialization of your Flex application which can possibly take longer than a few milliseconds.

If you are building branded applications, every little detail counts in enforcing your brand identity upon your user. You want to remind them the positive experience they are having was brought to them by you. Nothing is more important than a first impression, and the first thing people see in a Flex application is the preloader. It is important that you spend adequate time on making it look good and consistent.

To make a custom preloader for Flex, you have to do 2 steps:

  1. Write a class that extends DownloadProgressBar
  2. Set the preloader property on your Application class to your preloader class.

No witty 3 step process here.

The purpose of extending DownloadProgressBar is to handle the various things that happen in the life cycle of preloading (yes, we have life cycles now, not just downloading of bits). You do not have to handle anything save the FlexEvent.INIT_COMPLETE. You could for example put some dots who are ridin’ spinnaz and that’s your preloader.

…or, you could handle all events, and duplicate the Flex one with a different design showing the download & initialization progress.

The steps for making a custom Flash Preloader for your Flex app are as follows:

  1. Make a 100 frame MovieClip. TextField optional (as is everything).
  2. Give MovieClip linkage ID with no class name.
  3. Compile your SWF (“Test Movie”)
  4. Write your own Preloader class in Flex Builder which uses your Flash MovieClip.
  5. Set the Appliction.mxml preloader property to your custom class.

Making Your Flash Symbol

In Flash, you make a MovieClip that is 100 frames long. This will be the preloading part of your preloader, the MovieClip that shows the progress of the SWF downloading. Notice I have both a 100 frame animation as well as a dynamic TextField. The TextField will have the percentage numbers (i.e. “73%”) put into it dynamically.

Notice, also that the TextField has an instance name. This is so I can target it with code. Keep in mind, even though we are giving the TextField an instance name, we’ll be targeting it with code in Flex. We won’t be writing any code in Flash.

Finally, I wrap my preloader in a MovieClip because I want the preloader to fade out when it’s done.

I make sure to give the preloader an instance name so I can “dot dot down” to the preloader through the animation. Dot dot down is Flash slang for using dot syntax to walk down the display tree to target a MovieClip you want to interact with via code. In our case, it could be:

_root.my_clip.preloader.amount_txt.text = "70%";

Omg, I used _root, lol, l@mz03, me fired.

Finally, you export your Symbol with a linkage ID. Exporting as Flash 8, AS2, you just fill in the linkage ID class. Don’t export as Flash 9, AS3. If we did that, we might as well write the class for the preloader , and that’s just too much work, and too much added file-size for a class that’s supposed to be simple and most of all lightweight. If you are using Flash CS3, just change your publish settings to Flash 8, AS2 or AS1.

Flex will look for this linkage ID name when you are embedding the MovieClip. Now compile your SWF and your done.

Custom Preloader Class

You then write your own Preloader class. Have it extend mx.preloaders.DownloadProgressBar. There are multiple ways to embed Flash content. For our purposes, we’ll embed to a class property.

If you look at the Preloader’s setter function, you’ll see we get a Sprite (1 frame MovieClip) that emits all the preloading events we’ll care about. In this case download progress, when the SWF has finished downloading, when the SWF starts to initialize classes, and when initialization is complete.

Our download progress & SWF download done functions will dig down into the Flash MovieClip, and show download progress in both the text field, as well as making the preload MovieClip symbol animate via gotoAndStop based on the download percentage. Since download percentages are 100%, it makes it pretty easy to figure out what frame to go to.

The initialization ones just show “Initializing…” in the TextField.

Unlike most Flex preloaders, we want ours to animate when done, and only THEN actually launch into our Flex application. You can accomplish this by not dispatching the complete event. Dispatching this let’s the Flex application know the preloader is done. In our case, we want to wait till the Flash animation is done before doing so. We add a framescript ( a function called when the Playhead reaches a frame) to frame 21. When the animation is done, it’ll hit this frame, call our preloader class’ function. This will stop the animation and dispatch the event, letting the Flex application know we’re ready.

Conclusion

That’s it! Keep in mind it’s hard to test these things locally on your box. In Flash, we have the bandwidth profiler, but there is no such thing in Flex. You can either use network throttlers, like Charles. Alternatively you can upload the files to your site, install the Firefox Web Developer Toolbar, and choose disable cache.

In the next part, we’ll be taking advantage of Flex as a statefull client, and getting all the data you need. This takes time, so we need a cool way to show this to user as well as making it fail gracefully.

Flash Preloader in FlexExample | Source | ZIP

47 Responses

  1. 姬无双

    Good stuiff..body.

  2. Jebac

    Sucks, I see blank blue screen for more than 10 seconds and then a preloader for half a second. Should I see something at the very beginning and then a smooth progress from 0 to 100? Sorry for the ‘sucks’ part, I’m struggling with the same problem for days now, I have users leaving because of that blank screen issue.

  3. The only time that happens is if:

    - you’re preloader is large; frame 1 will have to download before you show it; however, it’s not larger than frame 2, thus by the time you’re preloader is showing, it only shows for a millisecond.

    - you’re not using Flex, but Flash, and have components in the library exported for actionscript; they default to export on frame 1, thus you’re whole app has to dl before it’s shown.

  4. Hey guys,

    I thought I’d hijack this thread to ask a quick question about using the download progress events to measure the client’s bandwidth. The code for doing so seems fairly simple – although the measure is probably not 100% accurate:

    private function SWFDownloadProgress(event:ProgressEvent):void {
    if(typeof(beginTime)==’undefined’) {
    beginTime = getTimer();
    beginBytes = event.bytesLoaded;
    } else {
    kbps = Math.floor( ((event.bytesLoaded-beginBytes) * 8 / 1024) / ((getTimer()-beginTime)/1000) );
    trace(kbps + ‘ kbps’);
    }
    }

    Now, I’ve got a measure for kbps with the preload package. But can anyone help me make that variable accessible from the main application? That is, how do I read the kbps variable after the application has been loaded?

  5. Francis

    Where are the 2nd and the 3rd part?!

  6. Ross R

    I know this is far off-base since this article was written in 2007, but did you ever get around to making part 2 or 3 of this series? What you describe as being covered in part 2 is exactly what I am trying to figure out for myself right now, but I can’t find anything to help me get there at the moment.

  7. [...] Tutaj jest ciekawy opis jak to zrobić. [...]

  8. [...] skinning the default Flex preloader – mx.preloaders.DownloadProgressBar – you should continue with Jesse Warden’s great article on the topic. But before proceeding with the implementation of the IPreloaderDisplay [...]

  9. [...] All our projects use the same preloader. Like many people, we based our preloader on Jesse Warden’s tutorial. [...]

  10. Derek

    Hey guys! Is there any way to access FlashVars or a variable from an external resource module to display a message in a different language? I have made many multi-language applications but have always had issues with changing the language on the custom preloader. Thanks for the help.