Leave That Thing Alone Blog
Flex 4 Custom Preloader
In this example were going to look at a way to create a custom preloader SWC in Flash Professional and use it
inside of a Flex 4 application by extending the SparkDownloadProgressBar class.
This preloader will display the progress percentage of loading and also a count of RSLs as they are being loaded, after loading is complete
the progress of initialization will be displayed. Both of the progresses will be displayed by a graphical progress bas and in text.
View Demo Preloader App (right click for source view)
The preloader may fly by, so lets first take a look at how this progress bar looks as it is loading the Flex app:
The next screenshot shows the progress as RSLs are being loaded:
Finally the progress of initialization, with a second progress bar:
Creating the Preloader SWC in Flash Pro
In Flash professional we create a custom preloader. In this example there are several layers which the design is created from. The layer 'prog_bar' and 'initilize_bar" hold shapes that we will use to resize to show progress. The 'loading text' layer contains some dynamic text that has Character Embedding for upper/lower/numbers. The layers look like this:
The custom preloader FLA can be found in the example by viewing source.
The FLA preloader is a movie clip and its properties are set for "Export for ActioScript" the "Class" property is set to "PreloaderDisplay" this allows us to have a PreloaderDisplay.swc created when this FLA is published.
In the first frame of the FLA "actions" layer we create the functions to set the two different progress bars:
//reset
setMainProgress(0);
setInitalizeProgress(0);
loading_txt.text = "";//function for setting main prgress bar
function setMainProgress(percent:Number):void {
prog_bar.width = percent * 275;
}
//function for setting the initilize bar
function setInitalizeProgress(percent:Number):void {
initialize_bar.width = percent * 275;
}
The final step is to "Publish" the FLA so that the SWC file is create, this SWC will be used in Flash Builder.
Creating the Custom Preloader in Flex 4
The first step is to place the PreloaderDisplay.swc in the "libs" folder, this will make the PreloaderDisplay and its methods available to Flex:
To define a custom preloader we will do this in the Flex application's Application file, we simply specify the preloader class:
<s:Application preloader="com.themorphicgroup.preload.Preloader" ...
In the Preloader class we will extend "SparkDownloadProgressBar".
The SparkDownloadProgressBar class displays download progress.
From Flex 4 docs: It is used by the Preloader control to provide user feedback while the application is downloading and loading.
The download progress bar displays information about two different phases of the application: the download phase and the initialization phase.
The Preloader.as extends "SparkDownloadProgressBar" and we will use the FLA PreloaderDisplay.swc by creating a variable called "preloaderDisplay":
public class Preloader extends SparkDownloadProgressBar {
private var preloaderDisplay:PreloaderDisplay;
...
To add the PreloaderDisplay we will override the SparkDownloadProgressBar's "createChildren" method, in this method we will create a new PreloaderDisplay and use the "addChild" method (SparkDownloadProgressBar inherits addChild from DisplayObjectContainer):
override protected function createChildren():void
{
if (!preloaderDisplay) {
preloaderDisplay = new PreloaderDisplay();
var startX:Number = Math.round((stageWidth - preloaderDisplay.width) / 2);
var startY:Number = Math.round((stageHeight - preloaderDisplay.height) / 2);
preloaderDisplay.x = startX;
preloaderDisplay.y = startY;
addChild(preloaderDisplay);
}
}
There are several methods that will override so that we can make updates to the PreloaderDisplay.swc. The rslProgressHandler method will be called each time a RSL is being loaded. We will use this method to set text indicating the current count of RSL being loaded:
private var rslBaseText:String = "loading: ";
override protected function rslProgressHandler(evt:RSLEvent):void {
if (evt.rslIndex && evt.rslTotal) {
//create text to track the RSLs being loaded
rslBaseText = "loading RSL " + evt.rslIndex + " of " + evt.rslTotal + ": ";
}
}
The next method we will override is setDownloadProgress. This method indicates the current download progress. in this method we will set the PreloaderDisplay.swc main progress bar and set the text:
override protected function setDownloadProgress(completed:Number, total:Number):void {
if (preloaderDisplay) {
//set the main progress bar inside PreloaderDisplay
preloaderDisplay.setMainProgress(completed/total);
//set percetage text to display, if loading RSL the rslBaseText will indicate the number
setPreloaderLoadingText(rslBaseText + Math.round((completed/total)*100).toString() + "%");
}
}
Finally we will look at overriding setInitProgress, this method indicates the progress of the Flex app as it initializes. We will set the text in PreloaderDisplay.swc and change the progress of the second initialize progress bar:
override protected function setInitProgress(completed:Number, total:Number):void {
if (preloaderDisplay) {
//set the initialization progress bar inside PreloaderDisplay
preloaderDisplay.setInitalizeProgress(completed/total);
//set loading text
if (completed > total) {
setPreloaderLoadingText("almost done");
} else {
setPreloaderLoadingText("initializing " + completed + " of " + total);
}
}
}
This blog entry does not cover every bit of code used in the preloader, so View Demo Preloader App right click for source view


Comments
I generally get a null pointer exception when I try to access the loading_txt.text, and I've got it to not give me a null pointer, but then nothing is ever shown on the screen during the loading. The null error also occurs when I try to call either of the set functions. Please let me know if there's a solution to this. Thanks.
I find this isnt working as before in flex3 for me. I would like to know what to do to stop errors in my application when I try to do addChild, I am prompted to do an addElement but that didn't work either. I am happy to use a.s. instead of mxml just want to get a method for me that will allow me to move past this blocker and actually get some work done..
I got it working i am up to designin my own.
Thanks
Connection to file:///Users/ahosford/Downloads/Flex4PreloaderExample/bin-debug/textLayout_1.0.0.595.swf halted - not permitted from file:///Users/ahosford/Downloads/Flex4PreloaderExample/bin-debug/Flex4PreloaderExample.swf
SecurityError: Error #2148: SWF file file:///Users/ahosford/Downloads/Flex4PreloaderExample/bin-debug/Flex4PreloaderExample.swf cannot access local resource file:///Users/ahosford/Downloads/Flex4PreloaderExample/bin-debug/textLayout_1.0.0.595.swf. Only local-with-filesystem and trusted local SWF files may access local resources.
at flash.net::URLStream/load()
at flash.net::URLLoader/load()
at mx.core::CrossDomainRSLItem/load()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\CrossDomainRSLItem.as:240]
at mx.core::RSLListLoader/loadNext()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\RSLListLoader.as:184]
at mx.core::RSLListLoader/load()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\core\RSLListLoader.as:156]
at mx.preloaders::Preloader/initialize()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\preloaders\Preloader.as:279]
at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::initia...()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:1925]
at mx.managers::SystemManager/initHandler()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2419]
[SWF] Users:ahosford:Downloads:Flex4PreloaderExample:bin-debug:Flex4PreloaderExample.swf - 3,394,428 bytes after decompression
The problem was solved by following directions here which amounted to no more than closing all browsers.
http://kb2.adobe.com/cps/518/cpsid_51814.html
Just the machine I am using is set up using Flash Builder on a Mac and not in Eclipse and the flexibility of where projects reside trips you up.
event which do progress the bar. Could you help me?
Am used that code in flex4 .its working but loading the bar going back and come processing for atleast 6 times.
how to set the one time bar loading in flex
how to load only one time in flex4
I have been working in Flex for the past 7 yrs and previously did Flash since the MX days.
Lost touch with Flash since I got on the Flex band-wagon.
This tutorial is fantastic, took me only a few minutes to grasp what you were accomplishing and after 2 days of beating my head against my monitor on trying to get the preloader built in Flex to work for me (IE hated it), I read your article and knocked out my preloader in 30 minutes.
Thanks for your article - keep up the great work.
Kenny
Thanks !
My
I would like to add a background image, how can I do that?
Thanks
http://forums.adobe.com/message/3700786
Add:
// Override to return true so progress bar appears during initialization.
override protected function showDisplayForInit(elapsedTime:int, count:int):Boolean
{
return true;
}
// Override to return true so progress bar appears during download.
override protected function showDisplayForDownloading(elapsedTime:int, event:ProgressEvent):Boolean
{
return true;
}