Aplicativos modernos

Tudo que você precisa saber sobre o controle ListView do WinJS

Rachel Appel

Rachel Appel
Você tem dados. Muitos dados. Você precisa apresentar esses dados de tal forma que os usuários possam acessar sem esforço e entendê-los quando estiverem em seu aplicativo. Os aplicativos expõem seus dados na forma de artigos de notícias, receitas, resultados de esportes, gráficos financeiros e muitos outros, todos desfilando em compartimentos de vários tamanhos pela tela e tentando atrair a atenção do consumidor. A grande maioria dos aplicativos atualmente no mercado apresentam dados em um formato de grade ou lista porque faz sentido, pois grades pequenas ou de médio porte são fáceis de serem consumidas, pesquisadas e filtradas pelas pessoas. De aplicativos empresariais a aplicativos pessoais e a qualquer que seja o aplicativo, as grades são a estrutura que sustenta os dados para uma espiada rápida.

Em aplicativos da Windows Store, é possível configurar essa estrutura para apresentação de dados usando o controle ListView. Se você for novo no desenvolvimento de aplicativos da Windows Store, poderá ficar totalmente informado lendo meu artigo de fevereiro de 2013, “Criar aplicativos da Windows Store com o HTML5 e o JavaScript” (msdn.microsoft.com/magazine/jj891058) e meu artigo de julho de 2013, “Dominando controles e configurações em aplicativos da Windows Store criados com JavaScript” (msdn.microsoft.com/magazine/dn296546).

Noções básicas do controle ListView

Disponível no HTML e no XAML, o ListView é o controle atual para apresentação de dados em um formato de grade ou lista. Em aplicativos da Biblioteca do Windows para JavaScript (WinJS) (o foco deste artigo), é possível usar o controle ListView definindo o atributo data-win-control em um elemento host <div> como “WinJS.UI.ListView,” como a seguir:

<div id="listView" data-win-control= "WinJS.UI.ListView"></div>

O <div> que hospeda o ListView não contém nenhum elemento filho. No entanto, contém informações básicas de configuração em um atributo chamado data-win-options. Data-win-options permite definir qualquer propriedade do controle ListView usando uma sintaxe declarativa na página HTML. Para usar o ListView adequadamente, você precisará aplicar as seguintes características a ele:

  • Os modelos de grupo e item do ListView.
  • As fontes de dados de grupo e item do ListView.
  • Se o ListView usa um layout de grade ou lista (o padrão é grade).

Você também deve especificar se o modo de seleção de item do ListView é único ou múltiplo (o padrão é múltiplo). Um ListView básico com o layout e as propriedades selectionMode definidos no atributo data-win-options fica assim:

<div id="listView" data-win-control= "WinJS.UI.ListView" data-win-options=
  "{ selectionMode: 'single', layout : {type: WinJS.UI.GridLayout} }" ></div>

Embora o código anterior defina um ListView, o ListView não funciona por si só. Ele precisa da ajuda do objeto WinJS.Binding.List. O objeto List associa matrizes preenchidas com objetos aos elementos HTML definidos nos modelos de item e grupo. Isso significa que o objeto List define os dados a serem exibidos enquanto o modelo define como exibi-los.

Criar modelos do ListView

Depois de ter o <div> para o ListView configurado, você pode prosseguir com a criação dos modelos para ele. O ListView depende dos modelos HTML para exibir os dados que são legíveis para o usuário. Felizmente, os modelos Grade, Divisão e Hub (o Hub está disponível no Windows 8.1) dos aplicativos da Windows Store contêm tudo o que é necessário para apresentar os dados em um formato de grade ou lista, incluindo dados de exemplo, controles ListView predefinidos e classes CSS predefinidas. É possível modificar esses modelos ou continuar e criar os seus próprios, se desejar. No entanto, observe que se você criar seus próprios modelos, você deverá seguir os princípios de design da interface de usuário moderna e implementar a silhueta do Windows 8, conforme descrito no Centro de Desenvolvimento dos aplicativos da Windows Store em bit.ly/IkosnL. Isso é feito para você quando usa os modelos internos do Visual Studio.

O ListView requer um modelo de item e, se você estiver agrupando dados, então, é necessário um modelo de cabeçalho também. Os elementos pai do item e os modelos de grupo são simples elementos <div> com o atributo data-win-control definido como “WinJS.Binding.Template”.

O modelo de cabeçalho deve conter links para cada grupo que, quando clicados, levam o usuário para uma página que lista itens pertencentes a esse grupo. Este é um exemplo de um padrão de navegação mestre/detalhes bastante comum. Na Figura 1, o <div> com a classe definida como “headertemplate” contém um elemento <button> associado à chave do grupo. Quando o usuário toca ou clica no botão, ela se move para uma página revelando os membros desse grupo.

Figura 1 Os modelos Cabeçalho e Item do controle ListView

<div class="headertemplate" data-win-control="WinJS.Binding.Template">
  <button class="group-header win-type-x-large win-type-interactive"
     data-win-bind="groupKey: key" 
     onclick="Application.navigator.pageControl
    .navigateToGroup(event.srcElement.groupKey)" 
     role="link" tabindex="-1"
     type="button">
    <span class="group-title win-type-ellipsis" data-win-bind=
      "textContent: title"></span>
    <span class="group-chevron"></span>
  </button>
</div>
<div class="itemtemplate" data-win-control="WinJS.Binding.Template">
  <div class="item">
    <img class="item-image" src="#" data-win-bind=
      "src: backgroundImage; alt: title" />
      <div class="item-overlay">
        <h4 class="item-title" data-win-bind="textContent: title"></h4>
        <h6 class="item-subtitle win-type-ellipsis" data-win-bind=
          "textContent: subtitle"></h6>
      </div>
  </div>
</div>

O modelo de item na Figura 1 consiste em marcas <div> que incluem uma imagem e dois campos de texto. Muitos dos dados atuais encontrados em aplicativos modernos são gráficos, portanto, há um elemento <img> dentro do modelo de item. Os dados de exemplo preenchem esse elemento com uma imagem que é simplesmente uma cor cinza sólida. A Figura 2 descreve o ListView padrão do layout Grade.

The Default ListView from the Grid Template, with Heading and Navigation Buttons Marked in Red
Figura 2 O ListView padrão do modelo Grade, com botões de título e navegação marcados em vermelho

Depois de codificar os modelos de item e de grupo, é hora de vinculá-los a alguns dados.

Dados e associação de dados com o controle ListView

JavaScript e JSON andam de mãos dadas (afinal, JSON é JavaScript Object Notation), portanto, depois de recuperar alguns dados JSON, simplesmente coloque-os em uma matriz e o objeto Windows.Binding.List a transformará em uma fonte de dados utilizável para o ListView. Em outras palavras, você não liga diretamente o ListView a uma matriz ou fonte de dados, significando que o objeto List serve como um intermediário entre o ListView e a fonte de dados. Isso acontece porque o objeto List transforma os dados em algo que o ListView sabe como usar. O próprio ListView apenas define a aparência e o layout da grade. O objeto List também fornece métodos para pesquisa, classificação, adição e exclusão de membros da matriz subjacente.

Examinar o arquivo \js\data.js revela um namespace Data além das matrizes que formam os dados de exemplo. A vantagem crucial é que as duas matrizes se combinam para formar um relacionamento mestre/detalhes. A propriedade de grupo de cada objeto na matriz sampleItems (detalhes) se refere a seu grupo na matriz sampleGroups (mestre), conforme mostrado na Figura 3.

Figura 3 Dados de exemplo em forma de matriz no modelo do projeto de grade

var sampleGroups = [
  { key: "group1", title: "Group Title: 1", 
     subtitle: "Group Subtitle: 1",
     backgroundImage: darkGray, description: groupDescription },
  { key: "group2", title: "Group Title: 2", 
     subtitle: "Group Subtitle: 2",
     backgroundImage: lightGray, description: groupDescription },
  { key: "group3", title: "Group Title: 3", 
     subtitle: "Group Subtitle: 3",
     backgroundImage: mediumGray, description: groupDescription }
];
var sampleItems = [
  { group: sampleGroups[0], title: "Item Title: 1",
    subtitle: "Item Subtitle: 1", 
    description: itemDescription,
     content: itemContent, backgroundImage: lightGray },
  { group: sampleGroups[0], title: "Item Title: 2",
     subtitle: "Item Subtitle: 2", 
     description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[0], title: "Item Title: 3", subtitle:
     "Item Subtitle: 3", 
     description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
  { group: sampleGroups[1], title: "Item Title: 1", subtitle:
     "Item Subtitle: 1", description: itemDescription,
     content: itemContent, backgroundImage: darkGray },
  { group: sampleGroups[2], title: "Item Title: 2", subtitle:
     "Item Subtitle: 2", description: itemDescription,
     content: itemContent, backgroundImage: mediumGray },
];

Certamente, substituirei os dados de exemplo com os seus próprios criando suas próprias matrizes, acessando os dados JSON ou XML, ou talvez chamando um serviço Web. Você não está amarrado a usar o namespace Data e em vez disso pode definir o seu próprio.

Próximo à parte superior do arquivo data.js está a seguinte linha de código:

var list = new WinJS.Binding.List();

A variável List é um contêiner de uma matriz. É possível adicionar uma matriz à List passando-a no método de construtor da List ou usando o método push:

generateSampleData().forEach(function (item) {
  list.push(item);
});

Fazer isso preenche a lista com dados da matriz e você agora está pronto para associar a lista e o ListView. Se estiver mantendo o código de modelo padrão, você deverá executar essa associação quando o aplicativo carregar de início, na função _initializeLayout do arquivo \js\default.js, como mostrado aqui:

listView.itemDataSource = Data.items.dataSource;
listView.groupDataSource = Data.groups.dataSource;

Certamente, dependendo do tamanho de seus dados, o tempo de carregamento pode variar, portanto, talvez seja necessário modificar o processo de carregamento. Use o seu bom senso a respeito de carregar dados na memória, lembrando-se da importância do desempenho para os usuários.

Observe que as fontes de dados de itens ou grupos são definidas como Data.items.dataSource e Data.groups.dataSource, respectivamente. Os membros chamados “itens” e “grupos” do namespace Data referem-se de volta às funções que criaram a matriz que contém os dados (isso é, groupedItems). A declaração do namespace Data no arquivo \js\data.js reflete essa noção e mostra outros membros públicos no namespace para se trabalhar com dados:

WinJS.Namespace.define("Data", {
  items: groupedItems,
  groups: groupedItems.groups,
  getItemReference: getItemReference,
  getItemsFromGroup: getItemsFromGroup,
  resolveGroupReference: resolveGroupReference,
  resolveItemReference: resolveItemReference
});

Os membros itens e grupos do namespace Data apontam para o objeto groupedItems, que construiu os dados apropriadamente. Tudo que você viu até agora no namespace Data está incluído nos modelos do projeto Visual Studio. Se optar por começar com um projeto em branco, você mesmo precisará moldar os dados criando métodos data-access similares em vez de depender dos membros do namespace Data.

Neste ponto, o ListView está completo com dados e as associações configuradas. É possível associar as propriedades dos objetos da fonte de dados aos elementos HTML usando o atributo data-win-bind, como mostrado aqui:

<h4 class="item-title" data-win-bind="textContent: title"></h4>

A linha de código anterior associa a propriedade de título ao elemento <h4> como parte de seu texto. A Figura 1 e a Figura 2 têm mais exemplos do atributo data-win-bind em ação.

Agora que você tem o ListView e o acesso aos dados prontos, é hora de prosseguir para definir o estilo do ListView.

Definir o estilo do controle ListView

Apresentação diz respeito a estilo. As bibliotecas WinJS contêm um conjunto completo de regras CSS com estilos predefinidos que você pode substituir para moldar o ListView de diversas maneiras. Se não estiver familiarizado com a definição de estilo dos controles WinJS, consulte meu artigo de outubro de 2013, “Criar uma interface de usuário dinâmica e moderna com CSS para aplicativos do WinJS” em msdn.microsoft.com/magazine/dn451447. É possível definir o estilo de todo o ListView substituindo a classe CSS do .win-listview. Junto com a definição de estilo do ListView, é possível definir as partes constituintes do ListView usando os seguintes seletores de classe:

  • .win-viewport: Define o estilo do visor do ListView. O visor é onde a barra de rolagem fica.
  • .win-surface: Define o estilo da área rolável do ListView. Essa área move-se quando um usuário rola.

Há duas formas de definir o estilo de itens no ListView. É possível aplicar estilos ao modelo de item por meio da classe .win-item, ou você pode substituir a classe .win-container. Lembre-se de que cada item do ListView é composto de diversos elementos HTML (consulte a Figura 1 para visualizar esse elementos). Como pode ser visto na Figura 1, os elementos <div> que formam o modelo de item contêm uma classe .item, .item-image, .item-overlay, .item-title e .item-subtitle. Você não encontrará nada disso definido nas folhas de estilo do sistema (isso é, ui-light e ui-dark), pois são para você definir o estilo.

Você deve estar ciente de uma porção de armadilhas envolvidas com a definição de estilo, especialmente em relação a quando aplicar margens e preenchimento ao controle ListView. Você pode analisar todas as vantagens e desvantagens de definir o estilo do ListView no Centro de Desenvolvimento dos aplicativos da Windows Store em bit.ly/HopfUg. Não se esqueça de criar estilos para todos os diversos estados de exibição de que seu aplicativo possa precisar.

O Windows 8.1 inclui algumas mudanças na definição de estilo do ListView referentes à especificidade do seletor filho/descendente. Isso ocorre porque um novo nó pertence à estrutura de árvore interna da página, portanto, você deve atualizar seus seletores CSS para conter o seletor de classe .win-itembox, como a seguir: .win-container | .win-itembox | .win-item.

Responder às mudanças do estado de exibição no ListView

Responder às novas exibições de ajuste e de tela cheia do Windows 8 é importante para ser aprovado no processo de certificação da Windows Store. A exibição de ajuste, junto com as exibições de tela inteira e tela cheia, é como os usuários podem organizar diversos aplicativos da Windows Store na tela. No Windows 8, os usuários podem redimensionar até duas janelas de aplicativo abertas, uma na exibição de tela cheia e outra na exibição de ajuste. No Windows 8.1, o número máximo de janelas aumenta para quatro e há mais opções para exibição de aplicativos. Essas exibições são chamadas de alta ou estreita no Windows 8.1 e são um pouco diferentes das exibições de ajuste e de tela cheia do Windows 8.

Isso significa que você deve codificar o controle ListView para alterar seu formato em resposta às mudanças nos estados de exibição do aplicativo. Esse é um processo chamado de design responsivo, e você pode obtê-lo usando as consultas de mídia do CSS. Se obter uma cartilha sobre as consultas de mídia do CSS, consulte minha postagem do blog, “Criar layouts de site móvel com as consultas de mídia do CSS”, em bit.ly/1c39mDx.

As consultas de mídia modelam o controle ListView para ajustar diferentes estados de exibição de uma forma que faça sentido para os diversos tamanhos e orientações de tela que acompanham cada exibição. Ao alternar para exibições altas, o ListView precisa se transformar em uma lista, como mostrado aqui:

listView.layout = new ui.ListLayout();

Posteriormente, quando o usuário voltar para o estado de exibição original, você deve definir o ListView de volta para uma grade:

listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });

Se desejar mudar a definição de estilo nos itens do ListView quando a tela mudar, adicione CSS à consulta de mídia no arquivo \css\default.css:

@media screen and (-ms-view-state: snapped) {...}

Você não precisa de uma consulta de mídia para exibições de tela cheia ou de tela inteira, pois elas usam as folhas de estilo padrão. No entanto, é possível usar diferentes consulta de mídia para uma variedade de tamanhos de tela, se necessário.

ListView e zoom semântico

A releitura do Windows na versão 8 implica em novas formas de visualizar, navegar e pesquisar dados. Isso significa que você precisa pensar de forma diferente sobre como abordar a pesquisa. Em vez dos usuários terem de digitar sentenças em caixas de pesquisa e filtrar listas de resultados, agora eles podem usar o zoom semântico para condensar os dados em seções digeríveis.

O zoom semântico permite que o usuário pesquise coisas usando um gesto de pinçagem (ou Ctrl + roda do mouse) para aplicar panorâmica ou reduzir e observar os dados em um formato agregado. Por exemplo, a página inicial do Windows comporta-se dessa maneira mostrando aos usuários todos os aplicativos disponíveis quando eles reduzem. Usar o zoom semântico em seu aplicativo é fácil, pois é simplesmente um controle do WinJS:

<div data-win-control="WinJS.UI.SemanticZoom">
  <!-- The control that provides the zoomed-in view goes here. -->
  <!-- The control that provides the zoomed-out view goes here. -->
</div>

O controle SemanticZoom é simplesmente um wrapper para um ou dois ListView, ou talvez o controle Repeater do HTML, novo no Windows 8.1.

Miscelânea sobre o ListView

Não use o ListView como um controle de layout para fins gerais. Em seu lugar, use o modelo de caixa CSS. No Windows 8.1, você deve considerar se é melhor usar um controle ListView ou um controle Repeater. Um controle Repeater é melhor se você não precisar de muita funcionalidade do controle e apenas precisar repetir o mesmo design em HTML diversas vezes. No momento da redação deste artigo, o Windows 8.1 está em versão de demonstração, portanto, poderão ocorrer algumas outras alterações no ListView além de outros componentes da API do aplicativo da Windows Store. Para obter mais informações sobre as alterações na API do Windows 8.1, consulte a documentação do Centro de Desenvolvimento em bit.ly/1dYTylx.

Rachel Appel é consultora, autora, mentora e antiga funcionária da Microsoft com mais de 20 anos de experiência no setor de TI. Ela dá palestras em importantes congressos do setor, como o Visual Studio Live!, o DevConnections, o MIX e muitos outros. Sua experiência está ligada a soluções de desenvolvimento que alinham negócios e tecnologia com foco na pilha de desenvolvimento da Microsoft e em Web aberta. Para obter mais informações sobre a Appel, visite seu site em rachelappel.com.

Agradecemos ao seguinte especialista técnico pela revisão deste artigo: Eric Schmidt (Microsoft)
Eric Schmidt é desenvolvedor de conteúdo na equipe de Conteúdo para desenvolvedores do Windows da Microsoft, escrevendo sobre a Biblioteca do Windows para JavaScript (WinJS). Anteriormente, ele criou exemplos de códigos para os aplicativos da plataforma Office enquanto estava na Divisão do Microsoft Office. Do contrário, ele passa seu tempo com a família, toca contrabaixo, cria videogames em HTML5 ou posta em blog sobre brinquedos de montar de plástico (historybricks.com).