範例:PlayList

PlayList 範例會在管理歌曲清單的音樂播放清單應用程式中,示範使用陣列的技巧。這些技巧包括:

若要取得此樣本的應用程式檔案,請參閱 www.adobe.com/go/learn_programmingAS3samples_flash_tw。您可以在 Samples/PlayList 檔案夾中找到PlayList 應用程式檔案,它是由下列檔案組成:

檔案

說明

PlayList.mxml

PlayList.fla

Flash (FLA) 或 Flex (MXML) 中的主應用程式檔案。

com/example/programmingas3/playlist/Song.as

代表單一歌曲資訊的值物件。由 PlayList 類別所管理的項目都是 Song 實體。

com/example/programmingas3/playlist/SortProperty.as

虛擬列舉項目可供使用的值代表 Song 類別的屬性,而 Song 物件清單就是依此屬性加以排序。

副主題

PlayList 類別概觀
在播放清單中新增歌曲
排序歌曲清單
將陣列元素合併成以字元分隔的字串

PlayList 類別概觀

PlayList 類別會管理一組 Song 物件。它所具備的公用方法,能夠將歌曲新增至播放清單 (addSong() 方法),並為清單中的歌曲排序 (sortList() 方法)。另外,此類別還包含唯讀的存取子屬性 songList,可以提供對播放清單中該組實際歌曲的存取。在 PlayList 類別內部,則會使用私有 Array 變數來追蹤歌曲:

public class PlayList
{
    private var _songs:Array;
    private var _currentSort:SortProperty = null;
    private var _needToSort:Boolean = false;
    ...
}

除了由 PlayList 類別用來追蹤歌曲清單的 _songs Array 變數之外,其它兩個私有變數則會追蹤清單是否需要排序 (_needToSort),以及在指定時間要以何種屬性為歌曲清單排序 (_currentSort)。

如同所有物件一樣,宣告 Array 實體只能算完成 Array 建立工作的一半而已。存取 Array 實體的屬性或方法之前,必須先加以實體化,而這是由 PlayList 類別的建構函式來進行。

    public function PlayList()
    {
        this._songs = new Array();
        // 設定初始排序作業。
        this.sortList(SortProperty.TITLE);
    }

建構函式的第一行會將 _songs 變數實體化,以供稍後使用。除此之外,並呼叫 sortList() 方法來設定初始的排序方式屬性。

在播放清單中新增歌曲

當使用者輸入新的歌曲至應用程式時,資料項目表格中的程式碼會呼叫 PlayList 類別的 addSong() 方法。

    /**
     * 在播放清單中新增歌曲。
     */
    public function addSong(song:Song):void
    {
        this._songs.push(song);
        this._needToSort = true;
    }

addSong() 中呼叫 _songs 陣列的 push() 方法,並在該陣列中新增傳遞至 addSong() 做為新元素的 Song 物件。不管之前是否曾經套用任何排序,藉由 push() 方法,便可以將此新元素加入至陣列結尾。這表示在呼叫 push() 方法之後,歌曲清單的排序可能不再正確,因此將 _needToSort 變數設定為 true。理論上來說,您可以立即呼叫 sortList() 方法,無須追蹤清單在特定時間是否已排序。然而實際上,只有在即將擷取歌曲之前,才需要排序歌曲清單。應用程式可以藉由延遲排序作業,避免執行不必要的排序動作,並在擷取歌曲清單前,才為新加入清單的歌曲進行排序。

排序歌曲清單

由於播放清單所管理的 Song 實體是相當複雜的物件,因此應用程式的使用者可能會希望根據不同的屬性為播放清單排序,例如歌曲名稱或出版年份等。在 PlayList 應用程式中,歌曲清單的排序工作可分為三個部分:識別清單應該以何種屬性排序、指出依照該屬性排序時需要使用哪些排序選項,以及執行實際的排序作業。

用於排序的屬性

Song 物件會追蹤數個屬性,包括歌曲名稱、作者、出版年份、檔案名稱、以及使用者所選取的歌曲類型。其中只有前三個項目才適用於排序。為方便開發人員使用,此範例包含 SortProperty 類別,此類別可做為列舉項目,而它的值則代表可用來進行排序的屬性。

    public static const TITLE:SortProperty = new SortProperty("title");
    public static const ARTIST:SortProperty = new SortProperty("artist");
    public static const YEAR:SortProperty = new SortProperty("year");

SortProperty 類別包含 TITLEARTISTYEAR 常數,每個常數都會儲存一個 String (內含相關聯之 Song 類別屬性的實際名稱,可用於排序)。在程式碼的其它部分,每當指定排序屬性時,就會使用列舉項目的成員來進行。例如,在 PlayList 建構函式中,最初是藉由呼叫 sortList() 方法為清單排序,如下所示:

        // 設定初始排序作業。
        this.sortList(SortProperty.TITLE);

由於用於排序的屬性已指定為 SortProperty.TITLE,因此歌曲會依照其標題加以排序。

依照屬性排序並指定排序選項

歌曲清單實際的排序工作是由 PlayList 類別在 sortList() 方法中執行,如下所示:

    /**
     * 根據指定的屬性,為歌曲進行排序。
     */
    public function sortList(sortProperty:SortProperty):void
    {
        ...
        var sortOptions:uint;
        switch (sortProperty)
        {
            case SortProperty.TITLE:
                sortOptions = Array.CASEINSENSITIVE;
                break;
            case SortProperty.ARTIST:
                sortOptions = Array.CASEINSENSITIVE;
                break;
            case SortProperty.YEAR:
                sortOptions = Array.NUMERIC;
                break;
        }
        
        // 執行資料的實際排序作業。
        this._songs.sortOn(sortProperty.propertyName, sortOptions);
            
        // 儲存目前的排序屬性。
        this._currentSort = sortProperty;

        // 記錄清單已經過排序。
        this._needToSort = false;
    }

依標題或藝人排序時,可以按照字母順序排序,但是依年份排序時,以數值排序是最合邏輯的方式。switch 陳述式可依據 sortProperty 參數所指定的值,用來定義適當的排序選項,而此排序選項則是儲存於變數 sortOptions 中。這裡又再次使用命名的列舉項目成員,而非硬式編碼值來區別屬性。

排序屬性和排序選項決定好之後,_songs 陣列就會藉由呼叫其 sortOn() 方法實際進行排序,並將這兩個值傳遞為參數。目前的排序屬性會記錄下來,以證明歌曲清單已完成排序。

將陣列元素合併成以字元分隔的字串

除了使用陣列來維護 PlayList 類別中的歌曲清單外,此範例中陣列也會用於 Song 類別,以協助管理特定歌曲所屬的類型清單。請考慮以下來自 Song 類別定義的程式碼片段:

private var _genres:String;

public function Song(title:String, artist:String, year:uint, filename:String, genres:Array)
{
    ...
    // 類型會當做陣列傳入,
    // 但是會儲存為以分號區隔的字串。
    this._genres = genres.join(";");
}

在建立新的 Song 實體時,用來指定歌曲所屬類型的 genres 參數會定義為 Array 實體。這樣可以方便將多個類型分組成可傳遞至建構函式的單一變數。然而在內部,Song 類別會將這些類型保留於私有 _genres 變數中,做為以分號區隔的 String 實體。Array 參數會藉由呼叫其 join() 方法,並以常值字串值 ";" 做為指定的分隔符號,以便轉換為以分號區隔的字串。

藉由相同的 Token,genres 存取子允許將類型設定或擷取為 Array:

    public function get genres():Array
    {
        // 類型會儲存為以分號區隔的 String,
        // 所以這些類型必須轉換為 Array,以便將它們傳回。
        return this._genres.split(";");
    }
    public function set genres(value:Array):void
    {
        // 類型會當做陣列傳入,
        // 但是會儲存為以分號區隔的字串。
        this._genres = value.join(";");
    }

genres set 存取子的表現方式和建構函式相同,它會接受 Array,並呼叫 join() 方法,將 Array 轉換為以分號區隔的 String。get 存取子則執行反向作業:呼叫 _genres 變數的 split() 方法,使用指定的分隔符號 (即之前的常值字串值 ";"),將 String 分割為值陣列。


Flash CS3

 

有新的意見加入至這個頁面時,傳送電子郵件給我 | 意見報告

目前頁面: http://livedocs.adobe.com/flash/9.0_tw/main/00000094.html