?
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