2

有没有人在 Flex 4 中成功实现了自定义预加载器?根据我的经验,当我在 Application 标签中使用 preloader="com.foo.MyPreloader" 指定自定义预加载器时,在 SWF 完全下载之前,预加载器不会显示,这违背了预加载器的目的!也许这是仍处于测试阶段的 Flex 4 框架中的一个错误?

4

3 回答 3

4

我一直在许多 Flex3 项目中使用这个示例。它仍在使用 Flex4 sdk:

我记得我从哪里得到它。当你说这个脚本不引用任何东西很重要时,你是对的......

<s:Application tag ...  preloader="com.YYY.XXX.shell.view.CustomPreloader"

自定义预加载器

package com.YYY.XXX.shell.view
{
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    import mx.events.FlexEvent;
    import mx.preloaders.DownloadProgressBar;

    public final class CustomPreloader
        extends DownloadProgressBar
    {
        public  var loader : LoadScreen;
        private var _timer : Timer;

        public function CustomPreloader() 
        {
            super(); 
        }

        override public function initialize() : void
        {
            super.initialize();

            this.loader = new LoadScreen();
            this.addChild(this.loader);

            this._timer = new Timer(1);
            this._timer.addEventListener(TimerEvent.TIMER, handleTimerTick);
            this._timer.start();
        }

        override public function set preloader(preloader : Sprite):void 
        {                   
            preloader.addEventListener(ProgressEvent.PROGRESS,  SWFDownLoadScreen);
            preloader.addEventListener(Event.COMPLETE,          SWFDownloadComplete);
            preloader.addEventListener(FlexEvent.INIT_PROGRESS, FlexInitProgress);
            preloader.addEventListener(FlexEvent.INIT_COMPLETE, FlexInitComplete);
        }

        private function SWFDownLoadScreen(event : ProgressEvent) : void
        {
            var prog : Number = event.bytesLoaded / event.bytesTotal * 100;
            if (this.loader)
            {
                this.loader.progress = prog;
            }
        }

        private function handleTimerTick(event : TimerEvent) : void
        {
            this.stage.addChild(this);
            this.loader.x = (this.stageWidth  - this.loader.width)  / 2;
            this.loader.y = (this.stageHeight - this.loader.height) / 2;
            this.loader.refresh();
        }

        private function SWFDownloadComplete(event : Event) : void {}

        private function FlexInitProgress(event : Event) : void {}

        private function FlexInitComplete(event : Event) : void 
        {      
            this.loader.ready = true;
            this._timer.stop();
            this.dispatchEvent(new Event(Event.COMPLETE));
        }

        override protected function showDisplayForInit(elapsedTime:int, count:int):Boolean
        {
            return true;
        }

        override protected function showDisplayForDownloading(elapsedTime:int,
                                                  event:ProgressEvent):Boolean
        {
            return true;
        }
    }
}

加载屏幕

package com.YYY.XXX.shell.view
{

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.utils.ByteArray;

    import mx.graphics.codec.PNGEncoder;

    public class LoadScreen extends Loader {

        //~ Settings ----------------------------------------------------------
        private static var _BarWidth     : int = 153;  // Progress bar width
        private static var _BarHeight    : int = 12;   // Progress bar height
        private static var _LogoHeight   : int = 153;   // Logo picture height
        private static var _LogoWidth    : int = 68;  // Logo picture width
        private static var _Padding      : int = 5;   // Spacing between logo and progress bar
        private static var _LeftMargin   : int = 0;    // Left Margin
        private static var _RightMargin  : int = 0;    // Right Margin
        private static var _TopMargin    : int = 1;    // Top Margin
        private static var _BottomMargin : int = 1;    // Bottom Margin

        private static var _BarBackground  : uint = 0xFFFFFF; // background of progress bar
        private static var _BarOuterBorder : uint = 0x737373; // color of outer border
        private static var _BarColor       : uint = 0x6F9FD5; // color of prog bar
        private static var _BarInnerColor  : uint = 0xFFFFFF; // inner color of prog bar

        //~ Instance Attributes -----------------------------------------------
        [Embed(source="/asset/embed/img/XXX.gif")]
        private var MyLogoClass: Class;
        private var _logo : Bitmap;
        private var _logoData : BitmapData;

        private var isReady  : Boolean = false;
        public  var progress : Number;

        //~ Constructor -------------------------------------------------------        
        public function LoadScreen()
        {
            super();
            this.progress = 0;
            this._logo = new MyLogoClass as Bitmap;
        }

        //~ Methods -----------------------------------------------------------
        public function refresh() : void
        {
            this._logoData = this.draw();
            var encoder : PNGEncoder = new PNGEncoder();
            var bytes   : ByteArray  = encoder.encode(this._logoData);
            this.loadBytes(bytes);
        }

        override public function get width() : Number
        {
            return Math.max(_BarWidth, _LogoWidth) + _LeftMargin + _RightMargin;
        }

        override public function get height() : Number
        {
            return _LogoHeight + _BarHeight + _Padding + _TopMargin + _BottomMargin;
        }

        private function draw() : BitmapData
        {
            // create bitmap data to create the data
            var data : BitmapData = new BitmapData(this.width, this.height, true, 0);

            // draw the progress bar
            var s : Sprite = new Sprite();
            var g : Graphics = s.graphics;

            // draw the bar background
            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);
            g.drawRect(px + 1, py + 1, progWidth, _BarHeight - 3);
            data.draw(s);

            // draw the logo
            data.draw(this._logo.bitmapData, null, null, null, null, true);
            return data;
        }

        public function set ready(value : Boolean) : void
        {
            this.isReady = value;
            this.visible = !this.isReady;
        }

        public function get ready() : Boolean { return this.isReady; }

    }
}
于 2010-05-30T13:10:24.197 回答
3

我觉得很愚蠢......我从预加载器中引用了我的一个主要应用程序类,从而导致我的所有类都被编译到预加载器中,这意味着它在加载所有内容之前无法显示预加载器。

供将来参考:仔细检查预加载器中的每个参考,确保只使用绝对必要的内容

于 2009-07-18T02:02:24.620 回答
1

这里有一个 Flex 4 自定义预加载器代码示例http://www.leavethatthingalone.com/blog/index.cfm/2009/11/11/Flex4CustomPreloader

于 2009-11-24T19:40:56.580 回答