Exemplo de matriz: PlayList

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

O exemplo Lista de reprodução demonstra técnicas de trabalho com matrizes, no âmbito de um aplicativo de lista de reprodução que gerencia uma lista de músicas. Estas técnicas são:

  • Criação de uma matriz indexada

  • Adição de itens a uma matriz indexada

  • Classificação de uma matriz de objetos por propriedades diferentes, usando opções de classificação diferentes

  • Conversão de uma matriz em uma string delimitada por caracteres

Para obter os arquivos de aplicativo desse exemplo, consulte www.adobe.com/go/learn_programmingAS3samples_flash_br . Os arquivos do aplicativo Lista de reprodução estão localizados na pasta Amostras/Lista de reprodução. O aplicativo consiste nos seguintes arquivos:

Arquivo

Descrição

PlayList.mxml

ou

PlayList.fla

O arquivo principal do aplicativo no Flash (FLA) ou no Flex (MXML).

com/example/programmingas3/playlist/PlayList.as

Uma classe que representa uma lista de músicas. Usa um Array para armazenar a lista e gerencia a ordenação dos itens da lista.

com/example/programmingas3/playlist/Song.as

O objeto de valor que representa informações sobre uma única música. Os itens gerenciados pela classe PlayList são ocorrências de Song.

com/example/programmingas3/playlist/SortProperty.as

Uma pseudo enumeração cujos valores disponíveis representam as propriedades da classe Song por meio da qual uma lista de objetos Song pode ser classificada.

Visão geral da classe PlayList

A classe PlayList gerencia um conjunto de objetos Song. Ela tem métodos públicos e adiciona uma música à lista de reprodução (o método addSong() ), além de classificar as músicas na lista (o método sortList() ). Além disso, a classe inclui uma propriedade de acesso somente leitura, songList , que fornece acesso ao conjunto real de músicas da lista de reprodução. Internamente, a classe PlayList mantém um registro das músicas usando uma variável de Array privada:

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

Além da variável _songs de Array, que é usada pela classe PlayList para manter um registro da lista de músicas, duas outras classes privadas mantém um registro que indica se a lista precisa ser classificada ( _needToSort ) e qual propriedade classifica a lista de músicas em um determinado momento ( _currentSort ).

Assim como com todos os objetos, declarar uma ocorrência de Array é apenas metade do trabalho de criação de uma matriz. Antes de acessar propriedades ou métodos de uma ocorrência de Array, essa classe deve ser instanciada, o que é feito no construtor da classe PlayList.

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

A primeira linha do construtor instancia a variável _songs , que fica pronta para ser usada. Além disso, o método sortList() é chamado para definir a propriedade sort-by inicial.

Adição de uma música à lista

Quando o usuário insere uma nova música do aplicativo, o código no formulário de entrada de dados chama o método addSong() da classe PlayList.

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

Em addSong() , o método push() da matriz _songs é chamado e adiciona o objeto Song que foi transmitido para addSong() como um novo elemento dessa matriz. Com o método push() , o novo elemento é adicionado ao final da matriz, independentemente de alguma classificação que tenha sido aplicada anteriormente. Isso significa que, depois que o método push() é chamado, a lista de músicas provavelmente não será mais classificada corretamente, de modo que a variável _needToSort será definida como true . Teoricamente, o método sortList() poderia ser chamado imediatamente, não sendo mais necessário manter o registro que indica se a lista deve ou não ser classificada em um determinado momento. No entanto, na prática, não é necessário classificar a lista de músicas imediatamente antes que ela seja recuperada. Adiando a operação de classificação, o aplicativo não executará uma classificação desnecessária se, por exemplo, várias músicas forem adicionadas à lista antes de ser recuperada.

Classificação da lista de músicas

Como as ocorrências de Song gerenciadas pela lista de reprodução são objetos complexos, os usuários do aplicativo talvez queiram classificar a lista de reprodução de acordo com propriedades diferentes, como o título da música ou o ano de publicação. No aplicativo PlayList, a tarefa de classificar a lista de músicas tem três partes: identificar a propriedade que classifica a lista, indicar as opções de classificação que devem ser usadas ao classificar de acordo com essa propriedade e executar a operação de classificação real.

Propriedades de classificação

Um objeto Song mantém o registro de várias propriedades, incluindo o título da música, o artista, o ano de publicação, o nome do arquivo e um conjunto de gêneros definido pelo usuário ao qual a música pertence. Entre essas propriedades, apenas as três primeiras são práticas para classificação. Para facilitar o entendimento dos desenvolvedores, o exemplo inclui a classe SortProperty, que age como uma enumeração com valores que representam as propriedades disponíveis para classificação.

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

A classe SortProperty contém três constantes ( TITLE , ARTIST e YEAR ), que armazenam uma string com o nome real da propriedade associada da classe Song que pode ser usada para classificação. No restante do código, sempre que uma propriedade de classificação for indicada, o membro de enumeração será usado. Por exemplo, no construtor PlayList, a lista é classificada inicialmente chamando o método sortList() do seguinte modo:

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

Como a propriedade de classificação é especificada como SortProperty.TITLE , as músicas são classificadas de acordo com o título.

Classificação por propriedade e especificação das opções de classificação

A classificação real da lista de músicas é realizada pela classe PlayList no método sortList() do seguinte modo:

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

Quando a classificação é feita por título ou artista, faz sentido classificar em ordem alfabética, mas, quando a classificação é feita por ano, é mais lógico realizar uma classificação numérica. A instrução switch é usada para definir a opção de classificação adequada, armazenada na variável sortOptions , de acordo com o valor especificado no parâmetro sortProperty . Aqui, mais uma vez, os membros de enumeração nomeados são usados para diferenciar as propriedades, em vez de valores codificados.

Quando a propriedade e as opções de classificação são determinadas, a matriz _songs é realmente classificada chamando o método sortOn() e transmitindo esses dois valores como parâmetros. A propriedade de classificação atual é registrada, o que indica que a lista de músicas está classificada no momento.

Combinação de elementos de matriz em uma string delimitada por caracteres

Além de usar uma matriz para manter a lista de músicas na classe PlayList, neste exemplo, as matrizes também são usadas na classe Song para ajudar a gerenciar a lista de gêneros aos quais pertencem as músicas. Veja este snippet da definição da classe 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(";"); 
}

Ao criar uma nova ocorrência de Song, o parâmetro genres que é usado para especificar os gêneros das músicas é definido como uma ocorrência de Array. Desse modo, é fácil agrupar vários gêneros em uma única variável que pode ser transmitida para o construtor. No entanto, internamente, a classe Song mantém os gêneros na variável _genres privada como uma ocorrência de String separada por ponto-e-vírgula. O parâmetro Array é convertido em uma string separada por ponto-e-vírgula chamando seu método join() com o valor de string literal ";" como o delimitador especificado.

Com o mesmo token, os acessadores de genres permitem que os gêneros sejam definidos ou recuperados como uma matriz:

    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(";"); 
    }

O acessador genres set se comporta exatamente como o construtor: aceita uma matriz e chama o método join() para convertê-la em uma string separada por ponto-e-vírgula. O acessador get executa a operação oposta: o método split() da variável _genres é chamado, dividindo a string em uma matriz de valores que usa o delimitador especificado (o valor de string literal ";" como antes).