Przykład użycia tablic: lista odtwarzania

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Przykład PlayList stanowi ilustrację technik pracy z tablicami, w kontekście aplikacji do odtwarzania muzyki z listy odtwarzania umożliwiającej zarządzanie utworami. Techniki te są następujące:

  • Tworzenie tablicy indeksowanej

  • Dodawanie pozycji do tablicy indeksowanej

  • Sortowanie tablicy obiektów według różnych właściwości, za pomocą różnych opcji sortowania

  • Konwertowanie tablicy do łańcucha rozdzielanego znakami

Aby pobrać pliki tej przykładowej aplikacji, należy przejść na stronę www.adobe.com/go/learn_programmingAS3samples_flash_pl . Pliki aplikacji PlayList można znaleźć w folderze Samples/PlayList. Aplikacja składa się z następujących plików:

File

Opis

PlayList.mxml

lub

PlayList.fla

Główny plik aplikacji w formacie Flash (FLA) lub Flex (MXML).

com/example/programmingas3/playlist/PlayList.as

Klasa reprezentująca listę utworów. Lista jest przechowywana w obiekcie Array. Klasa zarządza sortowaniem elementów listy.

com/example/programmingas3/playlist/Song.as

obiekt stanowiący wartość, reprezentujący informacje o pojedynczym utworze. Pozycje zarządzane przez klasę PlayList są instancjami Song.

com/example/programmingas3/playlist/SortProperty.as

Pseudowyliczenie, którego dostępne wartości reprezentują właściwości klasy Song, wg której można posortować obiekty Song.

Przegląd klasy PlayList

Klasa PlayList umożliwia zarządzanie zestawem obiektów Song. Ma ona metody publiczne umożliwiające dodawanie utworów do listy odtwarzania (metoda addSong() ) oraz sortowanie utworów na liście (metoda sortList() ). Ponadto klasa ta zawiera właściwość metody uzyskiwania dostępu tylko do odczytu songList , który zapewnia dostęp do rzeczywistego zestawu utworów na liście odtwarzania. Wewnętrznie klasa PlayList przechowuje informacje o utworach za pomocą prywatnej zmiennej typu Array.

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

Poza zmienną _songs typu Array, używaną przez klasę PlayList do przechowywania informacji o liście utworów, w dwóch innych prywatnych zmiennych przechowywane są informacje o tym, czy konieczne jest sortowanie listy ( _needToSort ) i według jakiej właściwości lista utworów jest posortowana obecnie ( _currentSort ).

Podobnie jak w przypadku wszystkich obiektów, deklarowanie instancji Array to tylko połowa zadania polegającego na tworzeniu tablicy. Przed uzyskaniem dostępu do właściwości instancji Array lub jej metod konieczne jest utworzenie jej instancji, co odbywa się w konstruktorze klasy PlayList.

    public function PlayList() 
    { 
        this._songs = new Array(); 
        // Set the initial sorting. 
        this.sortList(SortProperty.TITLE); 
    }

Pierwszy wiersz konstruktora powoduje utworzenie wystąpienia zmiennej _songs , tak aby było gotowe do użytku. Ponadto wywoływana jest metoda sortList() w celu ustawienia początkowej właściwości odpowiadającej za sortowanie.

Dodawanie utworu do listy

Wprowadzenie nowego utworu do aplikacji przez użytkownika wiąże się z wywołaniem przez kod w formularzu wprowadzania danych metody addSong() klasy PlayList.

    /** 
     * Adds a song to the playlist. 
     */ 
    public function addSong(song:Song):void 
    { 
        this._songs.push(song); 
        this._needToSort = true; 
    }

Wewnątrz metody addSong() wywoływana jest metoda push() tablicy _songs , co powoduje dodanie obiektu Song przekazanego do metody addSong() jako nowego elementu tablicy. Nowy element jest dodawany na koniec tablicy za pomocą metody push() — niezależnie od tego, czy uprzednio wykonano jakiekolwiek sortowanie. Oznacza to, że po wywołaniu metody push() lista utworów prawdopodobnie nie będzie prawidłowo posortowana, a tym samym zmienna _needToSort przyjmie wartość true . Teoretycznie metoda sortList() mogłaby być wówczas wywoływana niezwłocznie, co eliminowałoby potrzebę przechowywania informacji o tym, czy lista jest posortowana. W praktyce jednak nie ma potrzeby ustawicznego sortowania listy jest to potrzebne wyłącznie na chwilę przed jej pobraniem. Odroczenie operacji sortowani oznacza, że aplikacja nie wykonuje zbędnych działań gdy, na przykład, do listy dodanych zostanie kilka otworów.

Sortowanie listy utworów

Ponieważ instancje Song zarządzane przez listy odtwarzania są dość złożonymi obiektami, użytkownicy tych aplikacji mogą życzyć sobie posortowania listy odtwarzania zgodnie z różnymi właściwościami, takimi jak typ utworu lub rok publikacji. W aplikacji PlayList zadanie sortowania listy utworów składa się z trzech części: identyfikacji właściwości, wg której lista będzie sortowania, wskazania opcji, jakich użycie będzie potrzebne do wykonania sortowania wg tej właściwości, oraz faktycznego wykonania operacji sortowania.

Właściwości sortowania

Obiekt Song przechowuje informacje o kilku właściwościach, w tym o tytule utworu, wykonawcy, roku wydania, nazwie pliku oraz określonych przez użytkownika gatunkach, do których ten utwór należy. Z powyższych właściwości tylko trzy praktycznie nadają się do sortowania. W celu ułatwienia prac programistom w przykładzie uwzględniono klasę SortProperty, która pełni rolę wyliczenia, którego wartości reprezentują właściwości dostępne do sortowania.

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

Klasa SortProperty zawiera trzy stałe, TITLE , ARTIST oraz YEAR , z których każda przechowuje ciąg zawierający rzeczywistą nazwę skojarzonej właściwości klasy Song, która może służyć do sortowania. W dalszej części kodu, ilekroć wskazana jest właściwość sortowania, jest ono wykonywane za pomocą elementu wyliczenia. Na przykład w konstruktorze PlayList lista jest początkowo sortowana przez wywołanie metody sortList() , zgodnie z poniższym przykładem.

        // Set the initial sorting. 
        this.sortList(SortProperty.TITLE);

Właściwość będącą podstawą sortowania określono jako SortProperty.TITLE , dlatego utwory są sortowane według tytułu.

Sortowanie według właściwości i określanie opcji sortowania

Faktyczne sortowanie listy utworów odbywa się w klasie PlayList w metodzie sortList() , zgodnie z poniższym przykładem.

    /** 
     * 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; 
    }

Podczas sortowania według tytułu lub wykonawcy rozsądne wydaje się sortowanie alfabetyczne, w przypadku roku wydania z kolei lepszy efekt da sortowanie liczbowe. Instrukcja switch służy do definiowania odpowiednich opcji sortowania, przechowywanych w zmiennej sortOptions , zgodnie z wartością określoną parametrem sortProperty . Również tutaj do rozróżniania właściwości są stosowane elementy wyliczenia, a nie wartości zapisane na stałe w kodzie.

Po określeniu właściwości oraz opcji sortowania tablica _songs jest faktycznie sortowana przez wywołanie metody sortOn() i przekazanie tych dwóch wartości jako parametrów. Bieżąca właściwość sortowania jest rejestrowana, podobnie jak fakt, że lista jest teraz posortowana.

Łączenie elementów tablicy w łańcuch rozdzielany znakami

Poza zastosowaniem tablicy do przechowywania listy utworów w klasie PlayList w tym przykładzie tablic użyto również w klasie Song w celu wsparcia zarządzania listą gatunków, do której należy dany utwór. Można rozważyć następujący fragment z definicji klasy 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(";"); 
}

Podczas tworzenia nowego wystąpienia klasy Song parametr genres , używany do określania gatunku (lub gatunków), do jakich utwór należy, jest definiowany jako wystąpienie klasy Array. Ułatwia to grupowanie wielu gatunków w pojedynczej zmiennej, przekazywanej następnie do konstruktora. Wewnętrznie jednak klasa Song przechowuje gatunki w prywatnej zmiennej _genres w postaci wystąpienia klasy String z rozdzielaniem przy użyciu średników. Parametr typu Array jest konwertowany na ciąg rozdzielany średnikami przez wywołanie jego metody join() i podanie znaku rozdzielania jako wartości ciągu literału ";" .

Metody uzyskiwania dostępu do właściwości genres również pozwalają ustawiać i sprawdzać gatunki w formie obiektów 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(";"); 
    }

Metoda uzyskiwania dostępu set dla właściwości genres zachowuje się dokładnie tak samo jak konstruktor: Przyjmuje wyłącznie tablice i wywołuje metodę join() w celu ich przekonwertowania na ciąg rozdzielany średnikami. Metoda uzyskiwania dostępu get wykonuje operację przeciwną: Wywoływana jest metoda split() zmiennej _genres , co powoduje podzielenie obiektu String na tablicę wartości za pomocą zdefiniowanego separatora (wartości ciągu literału ";" , tak jak poprzednio).