自己定制Flex预加载器
Flex程序在加载时,会有一个灰色框的进度条,这个就是预加载器。 以下内容转载自:http://hi.baidu.com/airlonepig/item/c513f4de919fe95eddf9be87 ? ? ? Flex的预加载器为mx.preloaders.Preloader,Preloader加载应用程序和SystemManager传入的RSL共享库以及资源模块,Preloader并不包含加载器的界面,它是一个位置为(0,0)的空Sprite,采用mx.preloaders.DownloadProgressBar作为默认的皮肤。Preloader在加载过程中发送大量的事件,DownloadProgressBar和SystemManger通过监听Preloader的事件显示加载进度和跳帧。Application中preloader属性可以更改Preloader使用的加载界面,默认路径为mx.preloaders.DownloadProgressBar,如果你指定其他类,这些类将代替DownloadProgressBar被编译到项目中。修改加载界面可以分为两种方式,一是修改默认预加载器样式,即设置DownloadProgressBar的属性,二是通过制定类名自定义预加载器皮肤,Preloader作为功能类无需更改其逻辑。Application的usePreloader:Boolean属性可以禁用预加载器,但并不会改变Flex发布swf的结构,swf依然被编译为2帧并且使用Prelaoder加载,只是不创建加载外观而已。 修改预加载器样式
? ? DownLoadProgressBar提供了一些属性用于设置加载器样式,背景样式被声明为public,自定义加载界面后仍然可以设置这些属性,绘制的矢量界面和文本标签被声明为protected,自定义加载界面后将无法访问。 背景样式 ? ? ? ?DownloadProgressBar并不是只有中间显示的那个加载框,还拥有一个和舞台一样大小的背景色块,backgroundColor:uint,backgroundAlpha:Number属性可以设置加载器的背景颜色和透明度,backgroundImage:String和backgroundSize:String属性可以设置背景图片和大小,backgroundImage可以是文件名或类名,设置为文件名后会自动使用内部的Loader加载背景图片,但加载背景图片会增加加载swf加载时间,backgroundSize设置背景图片的缩放方式,如果为百分比,则”100%”表示拉伸到背景图片到完整大小,为”auto”表示图片保持大小不变。 ? ? ? Preloader在创建DownLoadProgressBar时会将背景设置为Application的背景颜色,然后调用DownLoadProgressBar的initialize()方法,我们可以通过覆盖initiliaze()方法更改背景设置,例如: override public function initialize():void { ???????super.initialize(); ???????backgroundImage="chuyin30.jpg"; ???????backgroundAlpha=0.2; } 加载框和加载条 borderRect:RoundedRectangle可以修改加载框的大小, barFrameRect:RoundedRectangle和barRect:RoundedRectangle可以修改加载槽和加载条的大小。 这两个属性都是只读的,修改需要覆盖get属性。没有修改加载框和加载条颜色的属性,加载框默认为透明的灰色,要自定义加载框和加载条,需要自定义加载界面。 修改加载标签 默认情况下DownloadProgressBar只显示了提示标签而没有显示进度标签,我们可以通过showPercentage:Boolean属性启用进度标签,showLabel:Boolean用于扩展显示自定义标签,labelRect:Retangle,labelFormat:TextFormat修改提示标签的大小和格式,percentRect:Rectangel和percentFormat属性设置进度文本的大小和格式。label:String属性为提示标签文本内容,加载应用程序时显示downloadingLabel:String属性的值,加载共享库时显示共享库的加载个数。 下图为修改过的DownloadProgressBar样式:
修改代码如下: package ???import mx.graphics.RoundedRectangle; ???import mx.preloaders.DownloadProgressBar; ? ???public class DownloadProgressBar1 extends DownloadProgressBar ???{ ???????public function DownloadProgressBar1() ???????{ ??????????super(); ???????} ???????override public function initialize():void ??????????super.initialize(); ??????????backgroundColor=0xAAAAAA; ??????????downloadingLabel=""; ??????????showPercentage=true; ??????? ???????override protected function get borderRect():RoundedRectangle ??????????return new RoundedRectangle(0,282,80,4); ???????override protected function get barFrameRect():RoundedRectangle ??????????return new RoundedRectangle(14,40,254,24); ???????override protected function get barRect():RoundedRectangle ???} 将DownloadProgressBar1指定给Application的preload属性即可看到效果。 自定义加载界面 ? ? 修改DownloadProgressBarPreloader的样式往往不能满足项目高级需求,例如需要将应用程序和资源下载进行分段显示,自定义加载界面需必须实现IPreloaderDisplay接口,这个接口包括外观的背景设置,所处的舞台大小等属性,但Flex的框架决定了IPreloaderDisplay与Preloader的耦合度很高,重新编写界面不容易,更多的时候我们选择继承DownLoadProgressBar类来简化操作,DownLoadProgressBar不仅实现IPreloaderDisplay接口,而且考虑的非常细致,例如加载所需的时间小于700m或启动进度超过总数的一半不显示加载界面。此外DownLoadProgressBar更是为我们扩展加载界面提供了有力的支持,某些方法定义了但内容却为空,这就是供我们扩展的提示。 DownloadProgressBar中的加载框、加载条都是通过代码绘制的,这使得默认加载器的体积很小,绘制的代码在createChildren()方法中,而更改进度显示的代码在setProgress()方法中,这两个方法实现了显示和逻辑的分离,通过覆盖这两个方法定制自己的加载界面可以在不改变加载逻辑的方式下进行,下面我们让Flex使用使用flash绘制的界面作为加载器的皮肤: 1.???在flash中新建影片剪辑,绘制所需的界面,如图:
? ? 将加载条命名为progressBar,进度文本命名为progressText,共享库进度条为rslBar,共享库文本为rslText,然后将元件导出为ActionScript,类名为DownloadProgressBarDisplay,将fla发布为swc导入Flex后便可以使用flash制作的素材了。 2.???覆盖定义 ? ? 覆盖定义之前我们要了解DownloadProgressBar内部一些实现,为了避免加载速度过快导致加载界面闪动一下就消失,createChildren()方法在700ms后才被调用,如果你想一开始就显示加载界面可以在构造函数中创建界面,但创建的界面不会自动居中,需要自己设置,此时可以利用基类提供的stageWidth:Number和stageHeight:Number属性访问舞台尺寸,但这个两个属性只有在执行createChildren()方法时才变得准确。默认绘制的加载条把显示进度分割为两个阶段,第一个阶段是加载阶段,应用程序将和rsl共享库同时加载,第二个阶段是Application初始化阶段,DownloadProgressBar使用属性DOWNLOAD_PERCENTAGE:uint进行百分比分割,你可以修改DOWNLOAD_PERCENTAGE更改默认进度条分割的百分比,也可以选择不进行分割、,下表为DownloadProgressBar对Preload添加的侦听器。 侦听器 说明 progressHandler(event:ProgressEvent):void 应用程序和共享库加载进度 rslProgressHandler(event:RSLEvent):void rsl加载进度 rslCompleteHandler(event:RSLEvent):void rsl加载完毕 rslErrorHandler(event:RSLEvent):void rsl加载出错 completeHandler(event:Event):void 应用程序和共享库加载完毕 initProgressHandler(event:Event):void 应用程序初始化进度 ? ? ? ?progressHandler()和initProgressHandler()都调用setProgress()方法设置进度,setProgress()反映加载总数。RSLEvent既可以反映rsl共享库的加载进度又可以反映加载数量,通过覆盖rsl的侦听器可以单独为rsl创建进度条。 ? ? 通过对DownloadProgressBar的观察使我们了解到,要定制加载界面,起码要覆盖createChildren()和setProgress()这两个方法,其它方法可以自己选择覆盖,MyDownloadProgressBar通过覆盖createChildren()和setProgress()方法引入flash制作的界面并且更新进度,如下: ???import flash.events.Event; ??? ???import mx.events.RSLEvent; ???public class MyDownloadProgressBar extends DownloadProgressBar ???????private var downloadDisplay:DownloadProgressBarDisplay; ???????public function MyDownloadProgressBar() ??????????downloadDisplay=new DownloadProgressBarDisplay(); ???????override protected function createChildren():void ??????????downloadDisplay.x=(stageWidth-downloadDisplay.width)/2; ??????????downloadDisplay.y=(stageHeight-downloadDisplay.height)/2; ??????????addChild(downloadDisplay); ???????override protected function rslProgressHandler(event:RSLEvent):void ??????????downloadDisplay.rslText.text="共享库"+"("+event.rslIndex+"/"+event.rslTotal+")"; ??????????downloadDisplay.rslBar.scaleX=event.bytesLoaded/event.bytesTotal; ???????override protected function setProgress(completed:Number,total:Number):void ??????????var per:Number=completed/total; ??????????downloadDisplay.progressBar.scaleX=per; ??????????downloadDisplay.progressText.text=(100*per).toFixed(0)+"%"; ? ? 我们在构造函数中创建了flash绘制的加载界面是避免createChildren()方法70ms后才执行而导致rslProgressHandler中无法访问downloadDisplay报错,由于stageWidth和stageHeight在createChildren()才能反映准确的舞台尺寸,因此在createChildren()中创建sownloadDisplay并且设置为舞台居中,rslProgressHandler使用了独立的进度条反映rsl加载进度,setProgress()反映总的加载进度。 3.???测试加载效果 ? ? 将Flex框架发布为共享库,然后再导入几个共享库一同进行测试,如下图:
? ? 总加载进度会在加载过程中有跳跃的现象,这是因为同时加载应用程序swf和rsl时,无法一时间获取所有rsl的大小,而在Application初始化时发生跳动是因为我们没有进行百分比分割。自定义加载界面后,DownloadProgressBar默认加载器的加载框和加载标签等样式变得没有意义,但加载背景仍然有效,我们仍然可以通过覆盖initiliaze()方法设置加载器的背景。 封装预加载器 如果能够将预加载器界面和代码封装到一个swc中,就可以让任何Flex工程使用,通过上面的例子修改如下: 1.???新建影片剪辑,放置DownloadProgressBarDisplay的实例,命名为preloadBox 2.???在flash路径库中导入Flex的framwork.swc 3.???取消DownloadProgressBarDisplay的导出 4.???将新影片剪辑导出为MyDownloadProgressBar MyDownloadProgressBar元件绑定的代码MyDownloadProgressBar.as如下: ??????????preloadBox.visible=false; ??????????x=(stageWidth-width)/2; ??????????y=(stageHeight-height)/2; ??????????preloadBox.visible=true; ??????????preloadBox.rslText.text="共享库"+"("+event.rslIndex+"/"+event.rslTotal+")"; ??????????preloadBox.rslBar.scaleX=event.bytesLoaded/event.bytesTotal; ??????????preloadBox.progressBar.scaleX=per; ??????????preloadBox.progressText.text=(100*per).toFixed(0)+"%"; } 在createChildren()方法中显示加载界面一来符合基类70ms的逻辑,再者舞台大小在createChildren()才具备准确的数值。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |