Preloader-Flex自訂預載進度條

來源:互聯網
上載者:User

當網路速度較慢時,如果在下載過程中介面沒有任何的提示或變化,使用者會感到煩躁,甚至抱怨開發商,這不是我們所希望的。進度條是很好的轉移注意力的方式,它讓使用者感覺到程式在正常運轉,可以耐心地等下去。

Preloader就是這樣一個類,它負責監聽Application、RSL和模組的下載和初始化進程的狀態,包括對下載過程的監聽,並且根據下載的狀態產生相應的初始化進程事件,包括:

FlexEvent.INIT_PROGRESS

FlexEvent.INIT_COMPLETE

ProgressEvent.PROGRESS

Event.COMPLETE

Preloader雖然發布初始化進程事件,但是並不直接顯示初始化進程,而是把顯示的工作交給一個顯示類來完成,我們稱這個類為載入顯示類。SystemManager在自己的initialize方法中會調用Preloader的initialize方法,並把載入顯示類的類名作為參數值傳遞給Preloader。在預設情況下,這個類被SystemManager指定為DownloadProgressBar(系統預設的進度條)。

如果我們在mx:application標記中使用preloader屬性指定載入顯示類,那麼指定的類名將作為參數傳遞給Preloader。Preloader類在initialize方法中根據參數中獲得的類名,建立載入顯示類,初始化顯示類的基本屬性,並把自己賦值給載入顯示類的preloader屬性。

載入顯示類必須實現IPreloaderDisplay介面,這是Preloader類的要求,因為Preloader正是把載入顯示類的執行個體強制轉化為IPreloaderDisplay介面來進行訪問的。通過IPreloaderDisplay介面的方法,Preloader才能夠完成對載入顯示類的基本屬性的設定。這些屬性包括backgroundImage和backgroundSize等,後面還會對IPreloaderDisplay介面詳細介紹。

有時候我們認為預設的載入顯示類不能滿足要求,希望實現更有特色的進度顯示。我們可以通過三種方法改變載入顯示類的表現形式:第一,修改預設顯示類進度條的屬性;第二,監聽載入進程事件,重新繪圖;第三,重新實現IPreloaderDisplay介面。這三種方法需要重新編寫代碼的工作量依次增加,當然,展現方式的自由度也依次增加了。

你也許會想,是否可以使用標記來修改進度條的屬性呢?首先,沒有提供修改進度條的屬性;其次,我們已經知道,preloader發生在第一幀,而Application和所有組件都是在第二幀初始化的。因此,即便能夠使用標記來修改進度條屬性,那也是在第一幀的工作做完之後,而這時進度條已經不再顯示了。所以,要想修改預設的Preloader顯示類的行為,只能夠通過修改代碼來完成。下面我們依次介紹改變預先載入預設顯示的三種方法。

1. 修改進度條的屬性

預先載入的預設顯示類是DownloadProgressBar(下載進度條),要修改下載進度條的顯示形式,就要從預設的DownloadProgressBar繼承,然後修改其屬性值,覆寫該類的方法,最後將新的實作類別指定給application的preloader屬性,從而實現不同風格的下載進度條。建立一個ActionScript類,從DownloadProgressBar繼承,屬性修改代碼如代碼清單3-1所示。

代碼清單3-1   修改進度條的屬性

import flash.geom.Rectangle;  import flash.text.TextFormat;     import mx.graphics.RoundedRectangle;  import mx.preloaders.DownloadProgressBar;     public class MyDownProBar extends DownloadProgressBar  {     [Embed(source="bcgImage.jpg")]   //進度條的背景圖片     [Bindable]     private var bcgImageClass: Class;         public function MyDownProBar()     {        super();                  downloadingLabel="下載中...";    //預設為 Loading        initializingLabel="初始化中..."   //預設為 Initializing        showLabel=true;       //是否顯示標籤,預設為true        showPercentage=true;  //是否顯示下載百分比,預設為true     }         override public function get backgroundImage():Object{         return bcgImageClass;     //背景圖片     }     override public function get backgroundSize():String{        return "30%"; //背景的尺寸,背景預設的尺寸是充滿整個舞台的     }     override public function get backgroundAlpha():Number{               return 0.5;   //控制項相對於背景的透明度     }     //override public function get backgroundColor():uint     //{     // return 0x00FF00;      //背景顏色,設定背景顏色或圖片只能選其一     //}     //進度條邊沿框的矩形地區(使進度條看起來是凹進去的)      override protected function get barFrameRect():RoundedRectangle{        return new RoundedRectangle(14, 40, 154, 10);      }     //進度條的矩形地區     override  protected function get barRect():RoundedRectangle {        return new RoundedRectangle(14, 39, 154, 12, 0);           }     //外圍邊框的矩形地區(使進度條看起來在一個panel裡)     override protected function get borderRect():RoundedRectangle {        return new RoundedRectangle(0, 0, 182, 60, 10);     }     //label 的顯示格式     override protected function get labelFormat():TextFormat {        var tf:TextFormat = new TextFormat();        tf.color = 0x333333;        tf.font = "Verdana";        tf.size = 12;        return tf;     }     //顯示label的矩形地區     override protected function get labelRect():Rectangle{        return new Rectangle(14, 17, 100, 18);     }             //百分比的文字格式     override protected function get percentFormat():TextFormat{        var tf:TextFormat = new TextFormat();        tf.align = "right";        tf.color = 0x000000;        tf.font = "Verdana";        tf.size = 12;        return tf;     }     //顯示百分比的矩形地區     override protected function get percentRect():Rectangle{        return new Rectangle(108, 4, 34, 16);     }  } 

代碼清單3-1中列出了可以修改的屬性和可以覆寫的方法,代碼只是對部分屬性的值做了修改,包括提示的字型以及進度條的高度。

注意   雖然backgroundImage、backgroundSize、backgroundAlpha以及backgroundColor都是public的屬性,但是通過直接賦值的方法並不能起到作用,必須覆蓋其get方法才能起作用。

背景圖片(backgroundImage)和背景顏色(backgroundColor)這兩個屬性不能同時設定,只能選其一。這兩個屬性的預設作用範圍是舞台(stage)的大小,可以通過覆寫backgroundSize的get方法來控制背景圖片和背景顏色的大小(相對於舞台的一個比例)。背景透明度(backgroundAlpha)是指進度條相對於背景的透明度,也必須通過覆寫get方法來修改。

注意,雖然Application也具有與上述相同的屬性,但是DownloadProgressBar的上述屬性是在第一幀顯示的屬性,而Application的上述屬性是控制第二幀的顯示。

在Application標記中添加屬性preloader=“flex.sample.MyDownProBar”,編譯運行Application,能看到修改後的進度條效果3-1所示,與預設的進度條(3-2所示)比較可以看出修改後的效果。

通過上述方法能夠修改進度條的邊框、背景圖片、下載提示標籤文本、初始提示標籤文本,以及是否顯示百分比等。但是,進度條的整體架構形式無法改變。如果想製作其他形式的進度條,需要採用另外兩種方式。

2. 監聽載入進程事件並重新繪圖

為了能夠實現自己繪圖,必須要能夠處理載入進程的相關事件,包括下載進程事件、下載完畢事件、初始化開始事件和初始化結束事件等。這些事件都是由preloader對象發送的,DownloadProgressBar類在設定自身的preloader屬性時對這些事件進行監聽。因此,為了能夠實現自行繪製進度條,就需要覆寫DownloadProgressBar的preloader屬性的set方法。具體實現如代碼清單3-2所示。

代碼清單3-2   監聽載入進程事件

import flash.display.Graphics;  import flash.display.Sprite;  import flash.events.*;  import flash.text.TextField;  import mx.containers.Canvas;  import mx.events.*;  import mx.preloaders.DownloadProgressBar;  public class MyDownProBar extends DownloadProgressBar  {     private var progressBar:Sprite;     private var myLabel:TextField     public function MyDownProBar(){        super();        myLabel=new TextField(); //建立顯示資訊的文字標籤         myLabel.x=200;        myLabel.y=200;        addChild(myLabel);     }     //覆蓋DownloadProgressBar方法,監聽相關事件     override public function set preloader(s:Sprite):void{        s.addEventListener(ProgressEvent.PROGRESS,inProgress);        s.addEventListener(Event.COMPLETE,complete);        s.addEventListener(FlexEvent.INIT_COMPLETE,initComplete);        s.addEventListener(FlexEvent.INIT_PROGRESS,initProgress);     }     //進程中自行繪圖     private function inProgress(e:ProgressEvent):  void {      var barWidth:Number = e.bytesLoaded/e.bytesTotal*100;        var g:Graphics = this.graphics; //繪圖區域         g.clear();        g.beginFill(0x88ff22);        g.drawRect(180,220, 100, 20);        g.endFill();        g.beginFill(0xff9900);        g.drawRect(180,220, barWidth, 20);        g.endFill();          myLabel.text=String(int(barWidth))+ " %";     }     private function complete(e:Event):void{        myLabel.text="下載完畢";     }     private function initComplete(e:FlexEvent):void{        myLabel.text="初始化完畢"       //初始完後要派發 Complete 事件,不然不會進入第二幀        dispatchEvent(new Event(Event.COMPLETE));     }     private function initProgress(e:FlexEvent):void{        myLabel.text="初始化..."; //進度條開始載入的方法     }  } 

上述代碼的實現效果,3-3所示。

實現的效果還是比較簡陋的,畢竟關於繪圖方面的代碼很簡單,要想實現賞心悅目的進度條,需要更多的繪圖代碼。

3. 重新實現IPreloaderDisplay介面

從Sprite類繼承,實現IpreloaderDisplay介面,相當於重新開發一個DownloadProgressBar。由於篇幅所限,本書不詳細討論實現細節,只對實現的原理稍作講解。首先,我們看一下IPreloaderDisplay要求實現的方法,如代碼清單3-3所示。

代碼清單3-3   IPreloaderDisplay介面

public interface IPreloaderDisplay extends IEventDispatcher  {      function get backgroundAlpha():Number;      function set backgroundAlpha(value:Number):void;      function get backgroundColor():uint;      function set backgroundColor(value:uint):void;      function get backgroundImage():Object;      function set backgroundImage(value:Object):void;      function get backgroundSize():String;      function set backgroundSize(value:String):void;      function get stageHeight():Number;   //舞台高度  
    function set stageHeight(value:Number):void;      function get stageWidth():Number;    //舞台寬度  
    function set stageWidth(value:Number):void;      function set preloader(obj:Sprite):void;      function initialize():void;          //進度條創  建後的初始化方法,配置進度條屬性  } 

可以看到,代碼中設定屬性的方法就是我們在第一種實現方式中設定的屬性,方法的實現可以參考代碼清單3-1中的代碼。而介面中preloader的set方法的實現和第二種實現方式中的preloader的set方法的內容是基本一致的。通過監聽下載和初始化事件,通過繪圖實現自己的Preloader。通過實現介面,可以更加自由地修改進度條的展示方式。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.