The Application class supports an application preloader that uses a download progress bar to show the download progress of an application SWF file. By default, the application preloader is enabled. The preloader keeps track of how many bytes have been downloaded and continually updates the progress bar.
The download progress bar displays information about two different phases of the application: the download phase and the initialization phase. The Application.creationComplete event dismisses the preloader.
The following example shows the download progress bar during the initialization phase:
The download progress bar is not displayed if the SWF file is on your local host or if it is already cached. If the SWF file is not on your local host and is not cached, the progress bar is displayed if less than half of the application is downloaded after 700 milliseconds of downloading.
To disable the download progress bar, you set the usePreloader property of the Application container to false, as the following example shows:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" usePreloader="false">
By default, the application preloader uses the DownloadProgressBar class in the mx.preloaders package to display the download progress bar. To create a custom download progress bar, you can either create a subclass of the DownloadProgressBar class, or create a subclass of the flash.display.Sprite class that implements the mx.preloaders.IPreloaderDisplay interface.
You can implement a download progress bar component as a SWC component or an ActionScript component. A custom download progress bar component that extends the Sprite class should not use any of the standard Flex components because it would load too slowly to be effective. Do not implement a download progress bar as an MXML component because it also would load too slowly.
To use a custom download progress bar class, you set the preloader property of the Application container to the path of a SWC component class or ActionScript component class. A SWC component must be in the same directory as the MXML file or in a directory on the classpath of your Flex application. An ActionScript component can be in one of those directories or in a subdirectory of one of those directories. When a class is in a subdirectory, you specify the subdirectory location as the package name in the preloader value; otherwise, you specify the class name.
The code in the following example specifies a custom download progress bar called CustomBar that is located in the mycomponents/mybars directory below the application's root directory:
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" preloader="mycomponents.mybars.CustomBar">
The operation of the download progress bar is defined by a set of events. These events are dispatched by the Preloader class. A custom download progress bar must handle these events.
The following table describes the download progress bar events:
|
Event |
Description |
|---|---|
| ProgressEvent.PROGRESS |
Dispatched when the application SWF file is being downloaded. The first PROGRESS event signifies the beginning of the download process. |
| Event.COMPLETE |
Dispatched when the SWF file has finished downloading. Either zero or one COMPLETE event is dispatched. |
| FlexEvent.INIT_COMPLETE |
Dispatched when the Flex application finishes initialization. This event is always dispatched once, and is the last event that the Preloader dispatches. The download progress bar must dispatch a COMPLETE event after it has received an INIT_COMPLETE event. The COMPLETE event informs the Preloader that the download progress bar has completed all operations and can be dismissed. The download progress bar can perform additional tasks, such as playing an animation, after receiving an INIT_COMPLETE event, and before dispatching the COMPLETE event. Dispatching the COMPLETE event should be the last action of the download progress bar. |
| FlexEvent.INIT_PROGRESS |
Dispatched when the Flex application completes an initialization phase, as defined by calls to the measure(), commitProperties(), or updateDisplayList() methods. This event describes the progress of the application in the initialization phase. |
| RslEvent.RSL_ERROR |
Dispatched when a Runtime Shared Library (RSL) fails to load. |
| RslEvent.RSL_LOADED |
Dispatched when an RSL finishes loading. The total bytes and total loaded bytes are included in the event object. This event is dispatched for every RSL that is successfully loaded. |
| RSLEvent.RSL_PROGRESS |
Dispatched when an RSL is being downloaded. The first progress event signifies the beginning of the RSL download. The event object for this event is of type RSLEvent. |
The DownloadProgressBar class defines an event listener for all of these events. Within your override of the DownloadProgressBar class, you can optionally override the default behavior of the event listener. If you create a custom download progress bar as a subclass of the Sprite class, you must define an event listener for each of these events.
The easiest way to create your own download progress bar is to create a subclass of the mx.preloaders.DownloadProgressBar class, and then modify it for your application requirements.
Your example might define custom strings for the download progress bar, or set the minimum time that it appears, as the following example shows:
package myComponents
{
import mx.preloaders.*;
import flash.events.ProgressEvent;
public class DownloadProgressBarSubClassMin extends DownloadProgressBar
{
public function DownloadProgressBarSubClassMin()
{
super();
// Set the download label.
downloadingLabel="Downloading app..."
// Set the initialization label.
initializingLabel="Initializing app..."
// Set the minimum display time to 2 seconds.
MINIMUM_DISPLAY_TIME=2000;
}
// 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;
}
}
}
You can use your custom class in a Flex application, as the following example shows:
<?xml version="1.0"?>
<!-- containers\application\MainDPBMin.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="myComponents.DownloadProgressBarSubClassMin">
<!-- Add a couple of controls that don't do anything. -->
<mx:Button label="Click Me"/>
<mx:TextInput text="This is a TextInput control."/>
</mx:Application>
The executing SWF file for the previous example is shown below:
In the following example, you create a subclass of the DownloadProgressBar class to display text messages that describe the status of the downloading and initialization of the application. This example defines event listeners for the events dispatched by the download progress bar to write the messages to flash.text.TextField objects.
package myComponents
{
import flash.display.*;
import flash.text.*;
import flash.utils.*;
import flash.events.*;
import mx.preloaders.*;
import mx.events.*;
public class MyDownloadProgressBar extends DownloadProgressBar
{
// Define a TextField control for text messages
// describing the download progress of the application.
private var progressText:TextField;
// Define a TextField control for the final text message.
// after the application initializes.
private var msgText:TextField;
public function MyDownloadProgressBar()
{
super();
// Configure the TextField for progress messages.
progressText = new TextField();
progressText.x = 10;
progressText.y = 90;
progressText.width = 400;
progressText.height = 400;
addChild(progressText);
// Configure the TextField for the final message.
msgText = new TextField();
msgText.x = 10;
msgText.y = 10;
msgText.width = 400;
msgText.height = 75;
addChild(msgText);
}
// Define the event listeners for the preloader events.
override public function set preloader(preloader:Sprite):void {
// Listen for the relevant events
preloader.addEventListener(
ProgressEvent.PROGRESS, myHandleProgress);
preloader.addEventListener(
Event.COMPLETE, myHandleComplete);
preloader.addEventListener(
FlexEvent.INIT_PROGRESS, myHandleInitProgress);
preloader.addEventListener(
FlexEvent.INIT_COMPLETE, myHandleInitEnd);
}
// Event listeners for the ProgressEvent.PROGRESS event.
private function myHandleProgress(event:ProgressEvent):void {
progressText.appendText("\n" + "Progress l: " +
event.bytesLoaded + " t: " + event.bytesTotal);
}
// Event listeners for the Event.COMPLETE event.
private function myHandleComplete(event:Event):void {
progressText.appendText("\n" + "Completed");
}
// Event listeners for the FlexEvent.INIT_PROGRESS event.
private function myHandleInitProgress(event:Event):void {
progressText.appendText("\n" + "App Init Start");
}
// Event listeners for the FlexEvent.INIT_COMPLETE event.
private function myHandleInitEnd(event:Event):void {
msgText.appendText("\n" + "App Init End");
var timer:Timer = new Timer(2000,1);
timer.addEventListener(TimerEvent.TIMER, dispatchComplete);
timer.start();
}
// Event listener for the Timer to pause long enough to
// read the text in the download progress bar.
private function dispatchComplete(event:TimerEvent):void {
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
You can use your custom class in a Flex application, as the following example shows:
<?xml version="1.0"?>
<!-- containers\application\MainDPB.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
preloader="myComponents.MyDownloadProgressBar">
<!-- Add a couple of controls that don't do anything. -->
<mx:Button label="Click Me"/>
<mx:TextInput text="This is a TextInput control."/>
</mx:Application>
The executing SWF file for the previous example is shown below:
You can define a custom download progress bar as a subclass of the Sprite class. By implementing your download progress bar as a subclass of Sprite, you can create a completely custom look and feel to it, rather than overriding the behavior built into the DownloadProgressBar class.
One common use for this type of download progress bar is to have it display a SWF file during application initialization. For example, you could display a SWF file that shows a running clock, or other type of image.
The following example displays a SWF file as the download progress bar. This class must implement the IPreloaderDisplay interface.
package myComponents
{
import flash.display.*;
import flash.utils.*;
import flash.events.*;
import flash.net.*;
import mx.preloaders.*;
import mx.events.*;
public class MyDownloadProgressBarSWF extends Sprite
implements IPreloaderDisplay
{
// Define a Loader control to load the SWF file.
private var dpbImageControl:flash.display.Loader;
public function MyDownloadProgressBarSWF() {
super();
}
// Specify the event listeners.
public function set preloader(preloader:Sprite):void {
// Listen for the relevant events
preloader.addEventListener(
ProgressEvent.PROGRESS, handleProgress);
preloader.addEventListener(
Event.COMPLETE, handleComplete);
preloader.addEventListener(
FlexEvent.INIT_PROGRESS, handleInitProgress);
preloader.addEventListener(
FlexEvent.INIT_COMPLETE, handleInitComplete);
}
// Initialize the Loader control in the override
// of IPreloaderDisplay.initialize().
public function initialize():void {
dpbImageControl = new flash.display.Loader();
dpbImageControl.contentLoaderInfo.addEventListener(
Event.COMPLETE, loader_completeHandler);
dpbImageControl.load(new URLRequest("assets/dpbSWF.swf"));
}
// After the SWF file loads, set the size of the Loader control.
private function loader_completeHandler(event:Event):void
{
addChild(dpbImageControl);
dpbImageControl.width = 50;
dpbImageControl.height= 50;
dpbImageControl.x = 100;
dpbImageControl.y = 100;
}
// Define empty event listeners.
private function handleProgress(event:ProgressEvent):void {
}
private function handleComplete(event:Event):void {
}
private function handleInitProgress(event:Event):void {
}
private function handleInitComplete(event:Event):void {
var timer:Timer = new Timer(2000,1);
timer.addEventListener(TimerEvent.TIMER, dispatchComplete);
timer.start();
}
private function dispatchComplete(event:TimerEvent):void {
dispatchEvent(new Event(Event.COMPLETE));
}
// Implement IPreloaderDisplay interface
public function get backgroundColor():uint {
return 0;
}
public function set backgroundColor(value:uint):void {
}
public function get backgroundAlpha():Number {
return 0;
}
public function set backgroundAlpha(value:Number):void {
}
public function get backgroundImage():Object {
return undefined;
}
public function set backgroundImage(value:Object):void {
}
public function get backgroundSize():String {
return "";
}
public function set backgroundSize(value:String):void {
}
public function get stageWidth():Number {
return 200;
}
public function set stageWidth(value:Number):void {
}
public function get stageHeight():Number {
return 200;
}
public function set stageHeight(value:Number):void {
}
}
}