9.18.自定义引导界面

9.18.1. 问题
你想自定义在下载和初始化Flex 程序时显示的引导界面。
9.18.2. 解决办法
通过生成mx.preloaders.DownloadProgressBar 类(默认的程序引导界面)的子类或者生成实现了mx.preloaders.IPreloaderDisplay 接口的flash.display.Sprite 的子类型两种方法创建自定义的引导界面。
9.18.3. 讨论
一个Flex 程序默认地由两个画面组成。第一个生成引导界面,该界面发出与程序的加载和初始化有关的一系列事件。默认的进度条依据这些事件更新其显示。下载接近完成时,系统管理器向第二个画面发出请求,同时继续生成和初始化程序。当程序快要完成初始化时,系统管理器将得到通知并去除引导界面。

这一过程由系统管理器进行内在处理,管理器初始化mx.preloaders.Preloader 类的一个实例监控你的程序下载和初始化状态。Preloader 实例实例化了指定的下载进度条,将其添加到显示列表并将IPreloaderDisplay 实现的preloader 属性设为本身。定义的Preloader实例能监听预加载器发出的许多事件,详情见表9-2.

要想创建一个自定义进度条以处理这些事件,你可以生成mx.preloaders.DownloadProgressBar 的子类或者生成实现了mx.preloaders.IPreloaderDisplay 接口的mx.display.Sprite 的子类,Sprite 本身就是DownloadProgressBar 组成部分。

DownloadProgressBar 类为表9-2 中列出的事件定义了保护型的事件处理器。你可以通过生成DownloadProgressBar 子类重载这些事件处理器以相应地修改和更新你的自定义显示:
+展开
-ActionScript
package oreilly.cookbook {
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.geom.Rectangle;
import mx.preloaders.DownloadProgressBar;
public class DPBSubclass extends DownloadProgressBar{
public function DPBSubclass(){
super();
// 下载完成后最短的显示时间
MINIMUM_DISPLAY_TIME = 3000;
// 设置初始化进程中的默认文本。
initializingLabel = "Download complete!\nInitializing...";
// 重载标签域以显示自定义文本
override protected function get labelRect():Rectangle{
 return new Rectangle(14, 5, 150, 30);
}
// 重载下载进度处理器以显示自定义文本。
override protected function progressHandler(event:ProgressEvent ):void{
super.progressHandler(event);
label = Math.round(event.bytesLoaded / 1000 ).toString()+ "k of "+ Math.round( event.bytesTotal / 1000).toString() + "k";
}
// 重载以确保在初始化和下载时显示进度条。
override protected function showDisplayForInit(elapsedTime:int,count:int):Boolean{return true;}
override protected function showDisplayForDownloading( elapsedTime:int,event:ProgressEvent):Boolean{ return true; }
}
}

本例重载DownloadProgressBar 定义的progressHandler 事件处理器显示自定义文本以响应引导器所发出PROGRESS 事件。在重载只读的labelRect 同时修改标签的显示域。显示文本布告的标签由父类内在地生成。若想将DPBSubclass 类设置为自定义引导界面,利用完整合法的类名设置<mx:Application>标记的preloader 属性,代码如下:
+展开
-XML
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxmllayout="vertical"
preloader="oreilly.cookbook.DPBSubclass">

<mx:Script>
<![CDATA[
// embed large audio file in order to see
// the preloader display.
[Embed(source="assets/audio/audio.mp3")]
private var _audio:Class;

]]>
</mx:Script>
</mx:Application>

当修改继承来的显示元素时,如果你想对事件处理有更细微的控制,你可以在DownloadProgressBar 的子类中修改公共的preloader 设置方法以定义你自己的的事件处理器。但如果你想对自定义引导界面的视觉组成有更多控制,你可以生成实现了IPreloaderDisplay 接口的Sprite 子类。

当生成IPreloaderDisplay 的实例时,你应当定义实现各种属性和方法。例如backgroundColor 和舞台尺寸等与视觉外貌有关的属性值由Preloader 实例在自定义引导界面实例化前赋值。Preloader 实例随后调用initialize 方法。IPreloaderDisplay 实例的preloader 属性是实现时应当赋予事件处理器的Preloader 实例。

下列代码片段实现IPreloaderDisplay 以生成自定义下载进度条:
+展开
-ActionScript
package oreilly.cookbook {
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;
import mx.events.FlexEvent;
import mx.preloaders.IPreloaderDisplay;
import mx.preloaders.Preloader;
public class CustomProgress extends Sprite implements IPreloaderDisplay{
private var _bgAlpha:Number;
private var _bgColor:uint;
private var _bgImage:Object;
private var _bgSize:String;
private var _stageHeight:Number;
private var _stageWidth:Number;
private var _preloader:Preloader;
private var _downloadBar:Shape;
private var _initBar:Shape;
private var _initField:TextField;
public function CustomProgress() {
_initField = new TextField();
_initField.defaultTextFormat = new TextFormat( 'Arial', 12, 0xFFFFFF, true);
_downloadBar = new Shape();
addChild( _downloadBar );
_initBar = new Shape();
addChild( _initBar );
}
// 初始化待显示的任何属性。
public function initialize():void {
_downloadBar.x = ( _stageWidth / 2 ) - 20;
_initBar.x = _downloadBar.x - 2;
_downloadBar.y = ( _stageHeight / 2 ) - 50;
_initBar.y = _downloadBar.y;
_initField.x = _initBar.x + 2;
_initField.y = _initBar.y + 100 - 15;
}
// 为Preloader实例定义事件处理器。
public function set preloader( obj:Sprite ):void {
_preloader = obj as Preloader;
_preloader.addEventListener( ProgressEvent.PROGRESS,downloadProgressHandler );
_preloader.addEventListener( FlexEvent.INIT_PROGRESS,initProgressHandler );
_preloader.addEventListener( FlexEvent.INIT_COMPLETE,initCompleteHandler );
}
public function get backgroundAlpha():Number { return _bgAlpha; }
public function set backgroundAlpha(value:Number):void{_bgAlpha = value;}
public function get backgroundColor():uint{ return _bgColor;}
public function set backgroundColor(value:uint):void{_bgColor = value;}
public function get backgroundImage():Object{return _bgImage;}
public function set backgroundImage(value:Object):void{_bgImage = value;}
public function get backgroundSize():String{return _bgSize;}
public function set backgroundSize(value:String):void{_bgSize = value;}
public function get stageHeight():Number{return _stageHeight;}
public function set stageHeight(value:Number):void{_stageHeight = value;}
public function get stageWidth():Number{return _stageWidth;}
public function set stageWidth(value:Number):void{_stageWidth = value;}
// 处理SWF 文件下载过程。
private function downloadProgressHandler( evt:ProgressEvent):void{
var perc:Number = ( ( evt.bytesLoaded / evt.bytesTotal )* 100 );
var top:Number = 100 - perc;
_downloadBar.graphics.clear();
_downloadBar.graphics.beginFill( 0xFF0000, 1 );
_downloadBar.graphics.moveTo( 0, 0 );
_downloadBar.graphics.lineTo( 10, 0 );
_downloadBar.graphics.lineTo( 10, perc * 0.9 );
_downloadBar.graphics.lineTo( 0, perc * 0.9 );
_downloadBar.graphics.lineTo( 0, 0 );
_downloadBar.graphics.endFill();
_initBar.graphics.clear();
_initBar.graphics.beginFill( 0xFFFFFF, 1 );
_initBar.graphics.moveTo( 0, 100 );
_initBar.graphics.lineTo( 2, 100 );
_initBar.graphics.lineTo( 2, top );
_initBar.graphics.lineTo( 0, top );
_initBar.graphics.lineTo( 0, 100 );
_initBar.graphics.endFill();
}
// 处理程序初始化过程。
private function initProgressHandler( evt:FlexEvent ):void{
_initField.text = "initializing...";
addChild( _initField );
}
// 处理下载和初始化的完成。
private function initCompleteHandler( evt:FlexEvent ):void{
var timer:Timer = new Timer( 3000, 1 );
timer.addEventListener( TimerEvent.TIMER_COMPLETE,notifyOfComplete );
timer.start();
}
// 通报下载和初始化的完成。
private function notifyOfComplete( evt:TimerEvent ):void{
dispatchEvent( new Event( Event.COMPLETE ) );
}
}
}

为通知系统管理器所有操作已经完成并且可从显示列表中去除引导界面,自定义引导界面需要在从Preloader 实例接收一个INIT_COMPLETE 事件后发出一个COMPLETE 事件。同样地,如果你在DownloadProgressBar 子类中重载公共preloader 设置方法或者生成IPreloaderDisplay 实例时,确保为INIT_COMPLETE 事件定义了处理器并相应地发出COMPLETE 事件。前面的例子中, COMPLETE 事件由计时器完成后发出的目的在于使用户能稍微多观察下初始化界面。

正如你在本节前面所做得一样,你在<mx:Application> 的声明中将CustomProgress 类赋值给preloader 属性值。例如:
+展开
-XML
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxmllayout="vertical"
preloader="oreilly.cookbook.CustomProgress">

<mx:Script>
<![CDATA[
// embed large audio file in order to see
// the preloader display.
[Embed(source="assets/audio/audio.mp3")]
private var _audio:Class;

]]>
</mx:Script>
</mx:Application>

你并不被限定于只使用绘图API 来自定义下载进度条。你可以嵌入图像元素,例如一幅图像或者一个SWF,同样用来修改程序引导界面的外观样貌。

加支付宝好友偷能量挖...


评论(0)网络
阅读(103)喜欢(0)flash/flex/fcs/AIR