转自: http://riashanghai.com/zh-hant/node/48
Flex 的默认的 Preloader, 平心而论,不是很好看。一个个性化的Preloader,基本上要包括三个部分。
1. 公司或者网站Logo,或者个性化的预载图片。好似是桌面软件的Splash Screen。
2. 载入数据的进度,文字形式的百分比。
3. 载入进度条。
preloader不像Flex项目中普通的部件可以通过CSS进行设置,是因为当程序初始载入时,CSS文件的设定还未被载入,所以不好通过CSS进行外观的控制。
这里有Ted把SWF,GIF 和 PNG 文件作为 Preloader 的教程。不过这里没有上述元素三合一的例子。
把网上的资料总结一下,这里放个三合一的例子。最终效果预览,
设置WEB程序的Preloader为自制的Preloader时,要修改主程序Application标签中的preloader属性,
<?xml version="1.0" encoding="utf-8"?> ...
这里的com.ibsol.view.Preloader是自定义Preloader类的路径。
Preloader要扩展DownloadProgressBar类才能设置自己的Preloader
package com.ibsol.view { 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.events.FlexEvent; import mx.preloaders.DownloadProgressBar; public class Preloader extends DownloadProgressBar { //显示进度的文字 private var progressText:TextField; //进度条 public var img:WelcomeScreen; //logo页面 public var logo:WelcomeLogo; private var _timer:Timer; public function Preloader() { super(); //加入logo logo = new WelcomeLogo(); this.addChild(logo); //加入进度条 img = new WelcomeScreen(); this.addChild(img); //加入进度文字 progressText = new TextField(); progressText.x = 40; progressText.y = 90; this.addChild(progressText); //进度条计时器初始化,我们实现进度条的原理就是不停的刷新进图条图片 //因为每次进度条的长度不同,所以就有进度条在走的效果 _timer = new Timer(1); _timer.addEventListener(TimerEvent.TIMER, drawTimerHandler); _timer.start(); } /** * override这个函数,来实现自己Preloader的设置,而不是用其默认的设置 */ override public function set preloader(value:Sprite):void { value.addEventListener(ProgressEvent.PROGRESS, progHandler); value.addEventListener(FlexEvent.INIT_COMPLETE, initCompleteHandler); //在这里设置预载界面居中 //如果在初始化函数中设置,会有stageWidth和最终界面大小不一致的错误,而导致不能居中 x = (stageWidth/2) - (300/2); y = (stageHeight/2) - (180/2); } private function progHandler(e:ProgressEvent):void { //计算进度,并且设置文字进度和进度条的进度。 var prog:Number = e.bytesLoaded/e.bytesTotal*100; progressText.text = "已下载 " + String(int(prog)) + "%"; if(img) { img.progress = prog; } } private function compHandler(e:Event):void { } private function initCompleteHandler(e:FlexEvent):void { //如果载入完毕,则停止刷新 img.ready = true; _timer.stop(); //测试专用。下载完毕后,不马上跳到程序的默认界面。而是停顿10秒后再跳入。 var timer:Timer = new Timer(10000, 1); timer.addEventListener(TimerEvent.TIMER, dispatchComplete); timer.start(); } private function initProgHandler(e:FlexEvent):void { } /** * 一定要分发这个事件,来通知程序已经完全下载,可以进入程序的默认界面了 */ private function dispatchComplete(event:TimerEvent):void { this.dispatchEvent(new Event(Event.COMPLETE)); } /** * 每个时钟周期都刷新进度条图片 */ private function drawTimerHandler(event:TimerEvent):void { img.refresh(); } } }
图片logo层的实现方式是
package com.ibsol.view { import flash.display.Loader; import flash.utils.ByteArray; public class WelcomeLogo extends Loader { [Embed(source="assets/preloader.png", mimeType="application/octet-stream")] public var WelcomeScreenGraphic:Class; public function WelcomeLogo() { this.loadBytes(new WelcomeScreenGraphic() as ByteArray); } } }
进度条和图片可以放在一层,但是考虑到个时钟周期,都要刷新进度条的图片。
毕竟LOGO不用每次都刷新,那么我们就分开放置了。进度条层的代码如下,