Adobe Flex 工程的 Application 為2幀的動畫,第1幀為 Pre-load,第2幀為 Application,如果想替換 Adobe Flex 原有的 Pre-loader,那么制作將非常的方便。制作一個新的 preload Component,在 Application 的 preloader 屬性中進行相關的引用就可以完成。

這次討論的不是在 AS3 工程中直接加載 SWF,而是通過 getDefinitionByName(name:String) 的方式對 Application 進行動態加載。

例子是 Unique Instance,詳細請見 Application.as 關于 Instance 的寫法。

  • 新建ActionScript工程:PreloaderApp
  • 設定Default Application:PreloaderApp.as
  • 新建需要動態加載的主工程代碼:Application.as
  • 設置工程屬性:Properties->ActionScript Compiler->Additional compiler arguments: -frame start Application

代碼:
PreloaderApp.as

package
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.utils.getDefinitionByName;
 
	public class PreloaderApp extends MovieClip
	{
 
		/**
		 * PreloaderApp Constructor.
		 */
		public function PreloaderApp()
		{
			this.addEventListener(Event.ADDED_TO_STAGE, handleToStage);
		}
 
		/**
		 * Handle ADDED_TO_STAGE event.
		 * @param event
		 */
		private function handleToStage(event:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, handleToStage);
 
			//stage setting
			stage.showDefaultContextMenu = false;
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			createChildren();
 
			addEventListener(Event.ENTER_FRAME, loadApplication);
 
			this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, handleProgress);
			this.loaderInfo.addEventListener(Event.COMPLETE, handleComplete);
		}
 
		private var _preLoadingText:TextField;
		/**
		 * createChildren
		 */
		private function createChildren():void
		{
			_preLoadingText = new TextField();
			_preLoadingText.text = "Loading...";
			_preLoadingText.textColor = 0x000000;
			_preLoadingText.x = (stage.stageWidth / 2) - (_preLoadingText.width / 2);
			_preLoadingText.y = (stage.stageHeight / 2) - (_preLoadingText.height / 2);
			_preLoadingText.autoSize = TextFieldAutoSize.CENTER;
			addChild(_preLoadingText);
		}
 
		/**
		 * Handle progress.
		 * @param event
		 */
		private function handleProgress(event:ProgressEvent):void
		{
			var percent:int = Math.floor(event.bytesLoaded / event.bytesTotal * 100);
			_preLoadingText.text = "Loading..." + percent + "%";
		}
 
		/**
		 * Handle load complete.
		 * @param event
		 */
		private function handleComplete(event:Event):void
		{
			this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, handleProgress);
			this.loaderInfo.removeEventListener(Event.COMPLETE, handleComplete);
		}
 
		/**
		 * Load main application.
		 * @param e
		 */
		private function loadApplication(event:Event):void
		{
			if (currentFrame == totalFrames)
			{
				removeEventListener(Event.ENTER_FRAME, loadApplication);
				stop();
 
				var cls:Class = getDefinitionByName("Application") as Class;
				addChild(new cls() as DisplayObject);
 
				removeChild(_preLoadingText);
				_preLoadingText = null;
			}
		}
	}
}

Application.as

package
{
	import flash.display.Sprite;
	import flash.events.Event;
 
	public class Application extends Sprite
	{
 
		private static var _instance:Application;
		/**
		 * Unique instance.
		 * @return
		 */
		public static function getInstance():Application
		{
			return _instance;
		}
 
		/**
		 * Application Constructor.
		 */
		public function Application()
		{
			super();
			addEventListener(Event.ADDED_TO_STAGE, initOnStage);
		}
 
		/**
		 * Handle ADDED_TO_STAGE event.
		 * @param event
		 */
		protected function initOnStage(event:Event):void
		{
			//remove ADDED_TO_STAGE listener.
			this.removeEventListener(Event.ADDED_TO_STAGE, initOnStage);
 
			//Set unique instance.
			if (!_instance)
				_instance = this;
 
			//...
		}
	}
}