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"?>
- <MX:APPLICATION xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" preloader="com.ibsol.view.Preloader">
- <MX:SCRIPT>
- ....</MX:SCRIPT></MX:APPLICATION>
<?xml version="1.0" encoding="utf-8"?>
<MX:APPLICATION xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" preloader="com.ibsol.view.Preloader">
<MX:SCRIPT>
....</MX:SCRIPT></MX:APPLICATION>
这里的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;
- //进度条
- private var img:WelcomeScreen;
- //logo页面
- private 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 public function set preloader(value:Sprite):void
- {
- value.addEventListener(ProgressEvent.PROGRESS,progHandler);
- value.addEventListener(FlexEvent.INIT_COMPLETE,initCompleteHandler);
- //在这里设置预加载页面居中
- //如果在初始化函数中设置,会有stageWidht和最终大小不一致的错误,而导致不能居中
- x=(stageWidth/2)-(300/2);
- y=(stageHeight/2)-(180/2);
- }
- private function progHandler(evt:ProgressEvent):void
- {
- //计算进度,并且设置文字进度和进度条的进度
- var prog:Number=evt.bytesLoaded/evt.bytesTotal*100;
- progressText.text="已下载"+String(int(prog))+"%";
- if(img)
- {
- img.progress=prog;
- }
- }
- private function compHandler(evt:Event):void
- {}
- private function initCompleteHandler(evt:FlexEvent):void
- {
- //如果载入完毕,则停止刷新
- img.ready=true;
- _timer.stop();
- //这里是测试,下载完毕后,不马上跳到程序默认界面,而是停留10秒后再跳入
- var timer:Timer=new Timer(1000,1);
- timer.addEventListener(TimerEvent.TIMER,dispatchComplete);
- timer.start();
- }
- private function initProgHandler(evt:FlexEvent):void
- {}
- private function dispatchComplete(evt:TimerEvent):void
- {
- //一定要分发这个事件,来通知程序已完全下载,可以进入程序的默认界面
- this.dispatchEvent(new Event(Event.COMPLETE));
- }
-
- //计时器监听事件
- private function drawTimerHandler(evt:TimerEvent):void
- {
- img.refresh();
- }
-
- }
- }
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;
//进度条
private var img:WelcomeScreen;
//logo页面
private 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 public function set preloader(value:Sprite):void
{
value.addEventListener(ProgressEvent.PROGRESS,progHandler);
value.addEventListener(FlexEvent.INIT_COMPLETE,initCompleteHandler);
//在这里设置预加载页面居中
//如果在初始化函数中设置,会有stageWidht和最终大小不一致的错误,而导致不能居中
x=(stageWidth/2)-(300/2);
y=(stageHeight/2)-(180/2);
}
private function progHandler(evt:ProgressEvent):void
{
//计算进度,并且设置文字进度和进度条的进度
var prog:Number=evt.bytesLoaded/evt.bytesTotal*100;
progressText.text="已下载"+String(int(prog))+"%";
if(img)
{
img.progress=prog;
}
}
private function compHandler(evt:Event):void
{}
private function initCompleteHandler(evt:FlexEvent):void
{
//如果载入完毕,则停止刷新
img.ready=true;
_timer.stop();
//这里是测试,下载完毕后,不马上跳到程序默认界面,而是停留10秒后再跳入
var timer:Timer=new Timer(1000,1);
timer.addEventListener(TimerEvent.TIMER,dispatchComplete);
timer.start();
}
private function initProgHandler(evt:FlexEvent):void
{}
private function dispatchComplete(evt:TimerEvent):void
{
//一定要分发这个事件,来通知程序已完全下载,可以进入程序的默认界面
this.dispatchEvent(new Event(Event.COMPLETE));
}
//计时器监听事件
private function drawTimerHandler(evt:TimerEvent):void
{
img.refresh();
}
}
}
图片logo层的实现方法:
- package com.ibsol.view
- {
- import flash.display.Loader;
- import flash.utils.ByteArray;
-
- /**
- * 图片logo层
- * */
- public class WelcomeLogo extends Loader
- {
- [Embed(source="img/logo.png",mimeType="application/octet-stream")]
- public var WelcomeScreenGraphic:Class;
- /**
- * 初始化方法
- * */
- public function WelcomeLogo()
- {
- this.loadBytes(new WelcomeScreenGraphic() as ByteArray);
- }
-
- }
- }
package com.ibsol.view
{
import flash.display.Loader;
import flash.utils.ByteArray;
/**
* 图片logo层
* */
public class WelcomeLogo extends Loader
{
[Embed(source="img/logo.png",mimeType="application/octet-stream")]
public var WelcomeScreenGraphic:Class;
/**
* 初始化方法
* */
public function WelcomeLogo()
{
this.loadBytes(new WelcomeScreenGraphic() as ByteArray);
}
}
}
进度条和图片可以放在一层,但是考虑到个时钟周期,都要刷新进度条的图片。
毕竟LOGO不用每次都刷新,那么我们就分开放置了。进度条层的代码如下,
- package com.ibsol.view
- {
- import flash.display.BitmapData;
- import flash.display.Graphics;
- import flash.display.Loader;
- import flash.display.Sprite;
-
- import mx.graphics.codec.PNGEncoder;
-
- public class WelcomeScreen extends Loader
- {
- //辅助属性,帮助进度条定位
- private static var _LogoWidth:int=300;
- private static var _LogoHeight:int=180;
- private static var _LeftMargin:int=5;
- private static var _RightMargin:int=5;
- private static var _Topmargin:int=1;
- private static var _BottomMargin:int=1;
- private static var _Padding:int=-60;
-
- //进度条的样式的设定,如边框颜色等
- private static var _BarWidth:int=200;
- private static var _BarHeight:int=12;
- private static var _BarBackground:uint=0xFFFFFF;
- private static var _BarOuterBorder:uint=0x737373;
- private static var _BarColor:uint=0x6F9FD5;
- private static var _BarInnerColor:uint=0xFFFFFF;
-
- private var isReady:Boolean=false;
- public var progress:Number;
- private var _logoData:BitmapData;
-
- /**
- * 初始化方法
- * */
- public function WelcomeScreen()
- {
- }
- override public function get width():Number
- {
- return Math.max(_BarWidth,_LogoWidth)+_LeftMargin+_RightMargin;
- }
- override public function get height():Number
- {
- return _LogoHeight+_LogoHeight+_Topmargin+_Padding;
- }
- /**
- * 进度条加载完毕后,隐藏进度条
- * */
- public function set ready(value:Boolean):void
- {
- this.isReady=value;
- // this.visible=!isReady;
- }
- public function get ready():Boolean
- { return isReady; }
-
- /**
- * 刷新方法,每个时钟周期都被调用这个函数
- * */
- public function refresh():void
- {
- _logoData=this.drawProgressBar();
- var encoder:PNGEncoder=new PNGEncoder();
- this.loadBytes(encoder.encode(_logoData));
- }
- /**
- * 生成进度条函数
- * */
- public function drawProgressBar():BitmapData
- {
- //创建bitmapdata对象
- var data:BitmapData=new BitmapData(this.width,this.height,true,0);
- //画出bitmapdata
- var s:Sprite=new Sprite();
- var g:Graphics=s.graphics;
- g.beginFill(_BarBackground);
- g.lineStyle(2,_BarOuterBorder,1,true);
- var px:int=(this.width-_BarWidth)/2;
- var py:int=_Topmargin+_LogoHeight+_Padding;
- g.drawRoundRect(px, py, _BarWidth, _BarHeight, 2);
- var containerWidth:Number=_BarWidth-4;
- var progWidth:Number=containerWidth*this.progress/100;
- g.beginFill(_BarColor);
- g.lineStyle(1, _BarInnerColor, 1, true);
- data.draw(s);
- return data;
- }
-
-
- }
- }
http://wwwflex.iteye.com/blog/808484