Actionscript项目中的自加载Preloader最佳实现【转】

这里我要说的是自加载,因为大家都知道flash要实现加载条无非两种方式,用单独的一个专用加载器外部加载,和自加载。由于外部加载这种方式需要编译好的预加载.swf文件,但我们许多项目更需要的是能够随时自定义的Preloader,这样能够在不同的项目中随机应变(类似Flex自带的preloader的实现)

因为要实现自加载,就不得不将侦听ProgressEvent.PROGRESS的代码与项目本身的代码混合在一起,最终只会让项目越来越大,并且如果不经过处理,flash将会加载完所有内容才会运行主程序。做到这一步,这就不得不想到MovieClip边加载边播放的特性,利用这个特性,我们可以实现不需要加载完整个flash就可以运行我们的加载条程序(和早期时间轴上写代码类似)。

package cc.lomo.preloader              
{              
    import flash.display.*;              
                                   
    /**              
     * 功能:SWF自身的加载条<br/>              
     * 用法:在需要实现自加载的类声明前加上<code>[Frame(factoryClass="cc.lomo.preloader.Preloader")]</code>              
     * @author vincent              
     */
    public class Preloader extends MovieClip              
    {              
        /**              
         * 是否本地运行               
         */
        protected var mNative:Boolean;              
        /**              
         * 模拟当前加载量(本地运行时)              
         */
        protected var mIndex:int    = 0;              
        /**              
         * 模拟最大加载量(本地运行时)              
         */
        protected const mMax:int    = 100;              
                                   
        public function Preloader()              
        {              
            addEventListener("addedToStage", addedToStageHandler);              
        }              
        protected function addedToStageHandler(e:*):void
        {              
            removeEventListener("addedToStage", addedToStageHandler);              
            //如果已经加载完,那估计就是本地运行了,这时候我们只有搞个假的Preloader了              
            mNative = loaderInfo.bytesLoaded == loaderInfo.bytesTotal;              
                                           
            addListeners();              
        }              
        /**              
         *               
         * 侦听加载事件              
         */  
        protected function addListeners():void
        {              
            if(mNative)              
                addEventListener("enterFrame", enterFrameHandler);              
            else
            {              
                loaderInfo.addEventListener("progress", progressHandler);              
                loaderInfo.addEventListener("complete", completeHandler);              
            }              
        }              
        /**              
         *               
         * 移除加载事件              
         */  
        protected function removeListeners():void
        {              
            if(mNative)              
                removeEventListener("enterFrame", enterFrameHandler);              
            else
            {              
                loaderInfo.removeEventListener("progress", progressHandler);              
                loaderInfo.removeEventListener("complete", completeHandler);              
            }              
        }              
        /**              
         * 用ENTER_FRAME模拟加载事件(本地运行时)              
         * @param e              
         *               
         */  
        protected function enterFrameHandler(e:*):void
        {              
            mIndex ++;              
            setProgress(mIndex / mMax);              
            mIndex > mMax && completeHandler();              
        }              
        /**              
         * 显示进度条              
         * @param value 进度比 0.0 ~ 1.0              
         *               
         */  
        protected function setProgress(value:Number):void
        {              
            graphics.clear();              
            if(value == 1)              
                return;              
            graphics.beginFill(0);              
            graphics.drawRect(0,stage.stageHeight/2, value * stage.stageWidth, 1);              
            graphics.endFill();              
        }              
        /**              
         * 加载事件              
         * @param e              
         *               
         */  
        protected function progressHandler(e:*):void
        {              
            setProgress(loaderInfo.bytesLoaded/loaderInfo.bytesTotal)              
        }              
        protected function completeHandler(e:*=null):void
        {              
            removeListeners();              
                                           
            addEventListener("enterFrame", init);              
        }              
        /**              
         * 加载完成后 构造主程序              
         */
        protected function init(e:*):void
        {              
            //currentLabels[1].name 获得第二帧的标签 也就是主程序的类名以"_"连接如:com_adobe_class_Main,我们需要将其转换为com.adobe.class::Main这样的格式              
            var prefix:Array = currentLabels[1].name.split("_");              
            var suffix:String = prefix.pop();              
            var cName:String =  prefix.join(".") + "::" + suffix;              
            //判断是否存在主程序的类              
            if(loaderInfo.applicationDomain.hasDefinition(cName))              
            {              
                //知道存在主程序的类了,删除enterFrame的侦听              
                removeEventListener("enterFrame", init);              
                                               
                var cls:Class = loaderInfo.applicationDomain.getDefinition(cName) as Class;              
                var main:DisplayObject = new cls();              
                parent.addChild( main );              
                parent.removeChild(this);              
            }              
        }              
                                       
    }              
}

 再来看看主程序怎么用的:

package
{            
    import flash.display.Sprite;            
    import flash.events.Event;            
                           
    [Frame(factoryClass="cc.lomo.preloader.Preloader")]            
    public class Test extends Sprite            
    {            
        public function Test()            
        {            
            super();            
            this.addEventListener(Event.ADDED_TO_STAGE, onadded);            
        }            
                           
        protected function onadded(event:Event):void
        {            
            trace("真实内容加载到舞台");            
        }            
    }            
}

 只需一句代码:

[Frame(factoryClass="cc.lomo.preloader.Preloader")]

这样就实现了加载条,Preloader类是越小越好,所以我没有导入flash.events.Event这个包,还可以压缩的更小,有兴趣的可以研究一下,就是这么简单

 

 

原文地址:https://www.cnblogs.com/ddw1997/p/2575130.html