陣列範例:PlayListFlash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本 PlayList 範例會在管理歌曲清單的音樂播放清單應用程式中,示範使用陣列的技巧。這些技巧包括:
若要取得此樣本的應用程式檔案,請參閱 www.adobe.com/go/learn_programmingAS3samples_flash_tw。您可以在 Samples/PlayList 檔案夾中找到 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(); // Set the initial sorting. this.sortList(SortProperty.TITLE); } 建構函式的第一行會將 _songs 變數實體化,以供稍後使用。除此之外,並呼叫 sortList() 方法來設定初始的排序方式屬性。 在播放清單中新增歌曲當使用者輸入新的歌曲至應用程式時,資料項目表格中的程式碼會呼叫 PlayList 類別的 addSong() 方法。 /** * Adds a song to the playlist. */ 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 類別包含 TITLE、ARTIST 和 YEAR 常數,每個常數都會儲存一個 String (內含相關聯之 Song 類別屬性的實際名稱,可用於排序)。在程式碼的其它部分,每當指定排序屬性時,就會使用列舉項目的成員來進行。例如,在 PlayList 建構函式中,最初是藉由呼叫 sortList() 方法為清單排序,如下所示: // Set the initial sorting. this.sortList(SortProperty.TITLE); 由於用於排序的屬性已指定為 SortProperty.TITLE,因此歌曲會依照其標題加以排序。 依照屬性排序並指定排序選項歌曲清單實際的排序工作是由 PlayList 類別在 sortList() 方法中執行,如下所示: /** * Sorts the list of songs according to the specified property. */ 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; } // Perform the actual sorting of the data. this._songs.sortOn(sortProperty.propertyName, sortOptions); // Save the current sort property. this._currentSort = sortProperty; // Record that the list is sorted. 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) { ... // Genres are passed in as an array // but stored as a semicolon-separated string. this._genres = genres.join(";"); } 在建立新的 Song 實體時,用來指定歌曲所屬類型的 genres 參數會定義為 Array 實體。這樣可以方便將多個類型分組成可傳遞至建構函式的單一變數。然而在內部,Song 類別會將這些類型保留於私有 _genres 變數中,做為以分號區隔的 String 實體。Array 參數會藉由呼叫其 join() 方法,並以常值字串值 ";" 做為指定的分隔符號,以便轉換為以分號區隔的字串。 藉由相同的字符,genres 存取子允許將類型設定或擷取為 Array: public function get genres():Array { // Genres are stored as a semicolon-separated String, // so they need to be transformed into an Array to pass them back out. return this._genres.split(";"); } public function set genres(value:Array):void { // Genres are passed in as an array, // but stored as a semicolon-separated string. this._genres = value.join(";"); } genresset 存取子的表現方式和建構函式相同,它會採用 Array,並呼叫 join() 方法,將 Array 轉換為以分號區隔的 String。get 存取子則執行反向作業:呼叫 _genres 變數的 split() 方法,使用指定的分隔符號 (即之前的常值字串值 ";"),將 String 分割為值陣列。 |
|