Question

I'm trying to create / use a pre-loader in my flex application. The preloader is a SWF file which has 100 frames (1 for every percent of the loader progress). Basically I am trying to Embed this SWF file in my application, display it on screen and change the frame number being displayed as the progress completes.

The code I have so far is (which extends Canvas):

[Embed("/../assets/preLoader.swf")]
private var SWFClass:Class;

private var _preLoader:MovieClip;

private var _progress:Number;

public function set progress(value:Number) : void {
    _progress = value;

    if(progress < 100) {
        _preLoader.gotoAndPlay(progress, null);
    }else {
        _preLoader.gotoAndStop(0, null);
    }
}   

[Bindable]
public function get progress() : Number {
    return _progress;
}



(Called on creationComplete event)          
private function init() : void {
    _preLoader = MovieClip(new SWFClass());

    this.addChild(_preLoader);

    _preLoader.play();
}

The error I am getting is:

TypeError: Error #1034: Type Coercion failed: cannot convert widgets::PreLoader_SWFClass@30b3be51 to mx.core.IUIComponent.at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::addingChild()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:3259]

Please help!

Was it helpful?

Solution

Use sprite instead of Canvas as a base class. Two reasons to do this:

  1. Canvas has a lot of dependencies (to the tune of 100k+ of flex components). You don't want to wait for all this to load before displaying your preloader

  2. Canvas is UIComponent container. Use it when you want to lay out UIComponents. In your case, you do not need complicated canvas layout logic - you just need to display a MovieClip. So don't use a canvas.

To answer your original question, SWFLoader and Image are UIComponents that know how to display Bitmaps and MovieClips. Do something like this instead:

var img:Image = new Image();
img.source = _preloader;
this.addChild(img);

OTHER TIPS

You need to have a wrapper over MovieClip that implements the IUIComponent in order to be able to pass to addChild(). From the addChild() documentation:

Note: While the child argument to the method is specified as of type DisplayObject, the argument must implement the IUIComponent interface to be added as a child of a container. All Flex components implement this interface.

You will need something like this:

public class MovieClipUIComponent extends UIComponent {
   public function MovieClipUIComponent (mc:MovieClip) {
      super ();

      mcHeight = mc.height;
      mcWidth = mc.width;

      // add your own magic

      addChild (mc);
   }
}

Warning: Untested code, should give you an idea only!

Hope this work I tried this.

[Embed(source="assets/yourSWF.swf", mimeType="application/octet-stream")]
public var SWF:Class;

_swfLoader = new Loader();
//nothing to do onComplete or onProgress method just to debug
// Add complete event listener
_swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
// Add progress event listener
_swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);


// Add error event listener. Critical if you don't want run time errors if there
// are problems loading the file.
_swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);

// Incase of loading Flex. Very important.
_swfLoader.addEventListener("mx.managers.SystemManager.isBootstrapRoot", systemManagerHandler);
_swfLoader.addEventListener("mx.managers.SystemManager.isStageRoot", systemManagerHandler);

// Load on the loader with a new URLRequest instance passing the path to
// it's constructor.
_swfLoader.loadBytes(new SWF());

// We have to addd the loader so it creation is done.
addChild(_swfLoader);

private function systemManagerHandler(e:Event):void {
            // Prevent default stops default behaviour here and thus stops some potential
            // run time errors.         
            e.preventDefault();
}

Have a look at the the Preloader class and the preloader property of the Application class.

As the documentation says, you definitely shouldn't extend the Flex UIComponent (or Image or SWFLoader) classes for a preloader.

Here are a few examples of how to go about customising the preloader:

http://www.pathf.com/blogs/2008/08/custom-flex-3-lightweight-preloader-with-source-code/

http://groups.adobe.com/posts/15d371c71d

http://www.webapper.net/index.cfm/2008/1/17/Flex-NotSo-Custom-Preloader

i found custom preloader using external swf code from this link
http://askmeflash.com/article_m.php?p=article&id=7

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top