Friday, May 25, 2012

Flex: Custom Preloader for Flex

Preloaders, something that you can never escape from. Hence I decided to share one of the ways to create a Flex Web Application Preloader.

Some Codings for the fancy preloader swf file.
//This variable will be shown on the screen...
var currentValue:int = 0;
//This variable stores the precentage loaded...
var newValue:int = 0;

//Add a ENTER_FRAME Event so that the preloader will
//animate from the currentValue to the newValue
this.addEventListener(Event.ENTER_FRAME, enterFrameEvent);

//This function will handle the calculation
//between the 2 variables 'currentValue' and 'newValue'
function enterFrameEvent(event:Event):void
{
 if(currentValue < newValue)
 {
  currentValue = newValue;
  updateContent();
 }else if(currentValue == 100)
 {
  this.removeEventListener(Event.ENTER_FRAME, 
     enterFrameEvent);
 }
}

//Update the Progress of the Preloader
//and the Progress Text
function updateContent():void
{
 preloader_mc.gotoAndStop(currentValue);
 percent_txt.text = currentValue + "%";
}

//This function will be called from the 
//Flex Application.
function setPreloader(value:int):void
{
 newValue = value;
}

Main Application File - FlexCustomPreloader.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute" width="100%" height="100%"
    preloader="com.zcs.CustomPreloader">
 <mx:Script>
  <![CDATA[
   //Embed a heavy dummy asset
   [Embed(source="../resources/music.swf")]
   public var contentClass:Class;
  ]]>
 </mx:Script>
 <mx:VBox width="100%" height="100%" 
    verticalAlign="middle"
    horizontalAlign="center">
  <mx:Label text="Hello World..."/>
 </mx:VBox>
</mx:Application>

Custom Preloader File - CustomPreloader.as
package com.zcs
{
 import flash.display.MovieClip;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.events.ProgressEvent;
 import flash.events.TimerEvent;
 import flash.text.TextField;
 import flash.utils.Timer;
 
 import mx.containers.VBox;
 import mx.controls.SWFLoader;
 import mx.events.FlexEvent;
 import mx.preloaders.DownloadProgressBar;

 public class CustomPreloader extends DownloadProgressBar
 {  
  //Embed a swf that will be used as a preloader
  [Embed(source="../resources/loading2.swf")]
  public var preloaderClass:Class;
  
  private var preloadMovieClip:MovieClip;
  
  //Like the Flash file, _currentPercent will be
  //shown as the current loading progress
  private var _currentPercent:int = 0;
  
  //_maxPercent will be the precentage of the file
  //that has been loaded
  private var _maxPercent:int = 0;
  
  public function CustomPreloader()
  {
   super();
   //Add the preloader swf to the Stage
   preloadMovieClip = new preloaderClass();
   addChild(preloadMovieClip);
  }
  
  // Define the event listeners for the preloader events.
  override public function set preloader(preloader:Sprite):void {
   preloader.addEventListener(
    ProgressEvent.PROGRESS, myHandleProgress);   
   preloader.addEventListener(
    Event.COMPLETE, myHandleComplete);
   
   preloader.addEventListener(
    FlexEvent.INIT_PROGRESS, myHandleInitProgress);
   preloader.addEventListener(
    FlexEvent.INIT_COMPLETE, myHandleInitEnd);
   
   preloader.addEventListener(Event.ENTER_FRAME,
    enterFrameEvent);
  }
  
  //This function will be used to access the content in the swf
  private function getSWFLoaderContent(tempSWF:MovieClip):*
  {
   var tempSWFContent:*;
   var tempSWFContent1:*;
   tempSWFContent = tempSWF.getChildAt(0);
   tempSWFContent = tempSWFContent.content;
   return tempSWFContent;
  }  

  private function enterFrameEvent(event:Event):void
  {
   //If the swf haven't beenn added to the stage 
   //yet, then we will not be doing anything
   if(getSWFLoaderContent(preloadMovieClip))
   {
   }else{
    return;
   }
   
   //Compare _currentPercent and _maxPercent...
   if(_currentPercent < _maxPercent)
   {
    _currentPercent ++;
   }
   
   //And pass it into the preloader swf file
   getSWFLoaderContent(preloadMovieClip).
    setPreloader(_currentPercent);
   
   //Once the flex app has been loaded completely...
   //Trigger a timer for 2 sec and execute 
   //dispatchComplete function after that
   if(_currentPercent == 99)
   {
    var timer:Timer = new Timer(2000,1);
    timer.addEventListener(TimerEvent.TIMER, 
     dispatchComplete);
    timer.start(); 
   }
  }
  
  // Event listeners for the ProgressEvent.PROGRESS event.
  private function myHandleProgress(event:ProgressEvent):void {
   _maxPercent = Math.floor((event.bytesLoaded / event.bytesTotal) * 98);
  }
  
  // Event listeners for the Event.COMPLETE event.
  private function myHandleComplete(event:Event):void {
  }
  
  // Event listeners for the FlexEvent.INIT_PROGRESS event.
  private function myHandleInitProgress(event:Event):void {
  }
  
  // Event listeners for the FlexEvent.INIT_COMPLETE event.
  // When everything is loaded, set _maxPercent to 99
  private function myHandleInitEnd(event:Event):void {
   _maxPercent = 99;
  }
  
  // Event listener for the Timer to pause long enough to 
  // read the text in the download progress bar.
  private function dispatchComplete(event:TimerEvent):void {
   //Pass 100 into the preloader.swf
   getSWFLoaderContent(preloadMovieClip).setPreloader(100);
   dispatchEvent(new Event(Event.COMPLETE));
  }
 }
}
* Click here for the demo.
^ Click here for the source files.

No comments:

Post a Comment