Como definir a identidade visual no seu ListView

[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente ]

Em Definindo a identidade visual de seus aplicativos da Windows Store, ensinamos você a incorporar a essência da sua marca no aplicativo e, ao mesmo tempo, aderir aos princípios de design da Microsoft. Discutimos sete aspectos do design da sua marca: cor, ícones, imagens, grade, layout, logotipo e tipografia.

Neste artigo, vamos falar sobre como personalizar a página de aterrissagem do seu aplicativo usando as seguintes técnicas:

  • Modificando modelos de itens ListView
  • Modificando tamanhos de itens ListView
  • Adicionando animações de itens ListView

Este tópico mostra como começar pelo modelo Aplicativo de Grade do Visual Studio e modificá-lo para criar páginas de aterrissagem como estas:

Página de aterrissagem da Padaria Contoso

Exemplo de Trailer de Lanches Contoso

Pré-requisitos

Quando usar um ListView

Sua primeira decisão é quais controles usar na sua página de aterrissagem. Para ver uma lista de controles HTML e de Biblioteca do Windows para JavaScript, veja a Lista de controles.

Se quiser apresentar um conjunto de dados como uma série de itens, como uma lista de emails, resultados de pesquisa ou um catálogo de itens para compra, use um ListView.

ListView exibe itens em um layout de lista ou grade. A maioria das páginas de aterrissagem que exibem itens usa o layout de grade do controle ListView, pois ele transborda automaticamente e rola na horizontal. Você pode personalizar os itens no ListView modificando o itemTemplate usado para exibi-los.

O Layout de Grade CSS3 e o sistema de grade do Windows 8

O sistema de grade é uma parte importante da aparência do Windows 8 e ajuda a alcançar uma unidade visual entre diferentes aplicativos e recursos. Com o layout de grade, você pode dividir o espaço para elementos na página e alinhar esses elementos facilmente na grade.

Nos nossos exemplos, também usamos o Layout de Grade CSS3 (Folhas de Estilos em Cascata, Nível 3), que é diferente do layout de grade do controle ListView. O Layout de Grade CSS3 fornece um estilo de grade generalizado para uma ampla variedade de usos, enquanto o ListView serve apenas para a exibição de correlações de dados. Com o Layout de Grade CSS3, você pode dispor perfeitamente os seus aplicativos e alinhar facilmente os elementos à grade.

Exemplo da Padaria Contoso

Vamos examinar o modelo Grid App padrão do Visual Studio e compará-lo com o exemplo da Padaria Contoso em Definindo a identidade visual de seus aplicativos da Windows Store. Veja a seguir uma captura de tela do modelo Grid App:

Aplicativo usando o modelo Aplicativo de Grade

Vamos comparar esse modelo com a página de aterrissagem da Padaria Contoso em Definindo a identidade visual de seus aplicativos da Windows Store. A Padaria Contoso dispõe seus itens de uma maneira personalizada que enfatiza a marca Contoso.

Página de aterrissagem da Padaria Contoso

Embora a página de aterrissagem da Padaria Contoso parece ser diferente do modelo Grid App, a diferença vem de apenas algumas modificações no HTML/CSS. Neste exemplo, supomos que os itens sejam interativos e que a seleção de um item leve o usuário até uma página de detalhes do grupo, com uma seleção de tipos de bolinhos, cupcakes e assim por diante. Um ListView que usa o layout de grade é um controle apropriado para essa página de aterrissagem.

Para converter o modelo Grid App na página de aterrissagem da Contoso, precisamos mudar o tamanho dos modelos de item, aumentar os tamanhos das imagens e adicionar descrições de itens.

  1. No Visual Studio, crie um novo aplicativo que use o modelo Grid App.

  2. Atualize o HTML itemtemplate em groupedItems.html. A principal mudança em comparação ao itemtemplate padrão é a adição de um terceiro elemento de título para exibir cada descrição de item.

        <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-text">
                    <h3 class="item-title" data-win-bind="textContent: title"></h3>
                    <h6 class="item-subtitle win-type-ellipsis" 
                        data-win-bind="textContent: subtitle"></h6>
                    <h6 class="item-detail" data-win-bind="textContent: description"></h6>
                </div>
            </div>
        </div>
    
  3. Agora, atualizamos os estilos em groupedItems.css. A principal mudança em groupedItems.css é mover o texto div abaixo da imagem, em vez de o sobrepor à imagem, e adicionar outra linha à grade para o elemento de detalhe do item.

    .groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface {
            margin-bottom: 60px;
            /* Decreased margin */
            margin-left: 35px;
            margin-right: 115px;
    }   
    .groupeditemspage .groupeditemslist .item {
           /* Changed row size and item size, centered text and changed text color */ 
            -ms-grid-columns: 1fr;
            -ms-grid-rows: 1fr 1280px;
            display: -ms-grid;
            height: 600px500px;
            width: 350px;
            text-align: center;
            color: rgb(160,160,160);
    
        }
    
            .groupeditemspage .groupeditemslist .item .item-image {
                   /* Increased image size and altered padding */
                height: 340px;
                width: 340px;
                padding: 0px 5px 20px 5px;
            }
    
            .groupeditemspage .groupeditemslist .item .item-text {
                /* Added a row to the grid and changed height and padding */
                -ms-grid-row: 2;
                -ms-grid-rows: 30px 21px 1fr;
                display: -ms-grid;
                padding: 30px 15px 2px 15px;
                height: 150px;
            }
    
                .groupeditemspage .groupeditemslist .item .item-text .item-title {
                    /* Changed font color */
                    -ms-grid-row: 1;
                    overflow: hidden;
                    font-size: 16pt;
                    color: rgb(200,200,200);
                }
    
                .groupeditemspage .groupeditemslist .item .item-text .item-subtitle {
                    -ms-grid-row: 2;
                }
                .groupeditemspage .groupeditemslist .item .item-text .item-detail {
                    /* All new CSS for the detail text */
                    -ms-grid-row: 3;
                    overflow:hidden;
                    padding-top: 20px;
                    height: 60px;
                    margin-left: 30px;
                    margin-right: 30px;
                }
    
  4. Remova os cabeçalhos de grupo de data.js. (A maneira mais fácil é simplesmente excluir o título de cada grupo).

Com essas mudanças, seu aplicativo tem agora esta aparência:

O aplicativo atualizado

Adicione algumas imagens e mude o plano de fundo e o título. Pronto! Você criou a página de aterrissagem da Padaria Contoso!

Exemplo de Trailer de Lanches Contoso

No próximo exemplo, criamos a página de aterrissagem do Trailer de Lanches Contoso a partir do modelo Grid App.

Exemplo de Trailer de Lanches Contoso

A página de aterrissagem do Trailer de Lanches Contoso atrai a atenção do usuário com imagens chamativas de vários tamanhos.

Ao contrário do exemplo anterior, essa página de aterrissagem requer algumas inclusões de JavaScript ao modelo, principalmente para adicionar a lógica que proporciona diferentes tamanhos aos itens em ListView. Mais uma vez, partimos do princípio de que os itens na página de aterrissagem sejam interativos e de que a escolha de um deles leve o usuário para sua respectiva exibição detalhada. Um ListView que usa o layout de grade é a ferramenta ideal para o trabalho. Mais uma vez, usamos o modelo Grid App como ponto de partida.

Para usar itens de vários tamanhos, primeiro precisamos escolher uma unidade base mínima. Usamos essa unidade para criar todos os itens da grade e, portanto, todos esses itens devem ser formados por múltiplos desse tamanho de grade. A menor dimensão de um dos itens na imagem a seguir é a altura dos itens na seção “Perto de Mim”, que é de aproximadamente 80px. A flexibilidade é maior com a dimensão horizontal. Para fins de simplicidade, também usamos 80px para a dimensão horizontal.

Essa imagem mostra a aparência da unidade base (o quadrado vermelho) em comparação a vários itens reais.

Tamanho do item base

Durante o cálculo de tamanhos de itens, cada tamanho deve ser igual a um múltiplo da unidade base, mas o preenchimento entre as unidades. A fórmula é:

item sizeₓ = m * base unit sizeₓ + (m -1) * item padding

item sizey = m * base unit sizey + (m -1) * item paddingy

em que m é um inteiro positivo e x e y indicam as dimensões x e y do tamanho do item e do preenchimento do item.

Se o tamanho base for muito pequeno em relação aos itens, ele prejudicará o desempenho do seu aplicativo. Como regra prática, o tamanho de qualquer item não deve ultrapassar algumas unidades base em qualquer direção.

  1. No Visual Studio, crie um novo aplicativo que use o modelo Grid App.

  2. Em groupedItems.html, crie um novo modelo de item chamado multisizebaseitemtemplate. Esse modelo de item é mais ou menos igual ao modelo de item padrão, mas com um cabeçalho de "descrição do item" adicionado e, portanto, podemos incluir a descrição do item além do título e do subtítulo na página de aterrissagem.

      <!-- Template tutorial HTML -->
        <div class="multisizebaseitemtemplate" data-win-control="WinJS.Binding.Template">
            <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>
                <h6 class="item-description" data-win-bind="textContent: description"></h6>
            </div>
        </div>
    
  3. Em groupedItems.js, crie uma função de modelo denominada multisizeItemTemplateRenderer antes da definição PageControl (ui.Pages.define).

    Usamos essa função para renderizar os itens ListView. É essa função que determina quais itens usam qual modelo de item. Iremos atribui-la à propriedade itemTemplate do controle ListView em uma etapa posterior.

     function multisizeItemTemplateRenderer(itemPromise) {
            return itemPromise.then(function (currentItem) {
                var content;
                // Grab the default item template used on the groupeditems page.
                content = document.querySelector(".multisizebaseitemtemplate");
                var result = content.cloneNode(true);
    
                // Change the CSS class of the item depending on the group, then set the size in CSS.
                switch (currentItem.groupKey) {
                    case "group1":
                        {
                            // For the first item, use the largest template.
                            if (currentItem.index == 0) {
                                result.className = "largeitemtemplate"
                            }
                            // Use the mediumlarge template for the second item
                            else if (currentItem.index == 2) {
                                result.className = "mediumlargeitemtemplate"
                            }
                            // Use the medium template for the third item, and any other items
                            else {
                                result.className = "mediumitemtemplate"
                            }
                            break;
                        }
                    default:
                        {
                            // Use the small template for the second group
                            result.className = "smallitemtemplate"
                        }
                }
                // Because we used a WinJS template, we need to strip off some attributes 
                // for it to render.
                result.attributes.removeNamedItem("data-win-control");
                result.attributes.removeNamedItem("style");
                result.style.overflow = "hidden";
    
                // Because we're doing the rendering, we need to put the data into the item.
                // We can't use data binding.
                result.querySelector(".item-image").src = currentItem.data.backgroundImage;
                result.querySelector(".item-title").textContent = currentItem.data.title;
                result.querySelector(".item-subtitle").textContent = currentItem.data.subtitle;
                result.querySelector(".item-description").textContent = currentItem.data.description;
                return result;
            });
        }
    
  4. Em groupedItems.js, adicione a função groupInfo, também fora da definição da página. Essa função instrui ListView a usar itens de vários tamanhos no modo de exibição, além de indicar o tamanho base desses itens. O tamanho base é o menor item mostrado na lista. Os demais itens deverão ser múltiplos desse tamanho para que os layouts funcionem corretamente.

     function groupInfo() {
        return {
            enableCellSpanning: true,
            cellWidth: 80,
            cellHeight: 80
        };
     }
    
  5. Agora, precisamos associar essas novas funções ao controle ListView.

    1. No groupedItems.js, mude a função _initializeLayout para mostrar uma lista plana de grupos.

      // Add the itemTemplate parameter as shown.
      _initializeLayout: function (listView, viewState, itemTemplate) {
          if (viewState === appViewState.snapped) {
              listView.itemDataSource = Data.groups.dataSource;
              listView.groupDataSource = null;
      
              // Add the following line of code.
              listView.itemTemplate = itemTemplate;
      
              listView.layout = new ui.ListLayout();
          } else {
      
                      listView.itemDataSource = Data.items.dataSource;
                      listView.groupDataSource = Data.groups.dataSource;
                      listView.layout = new ui.GridLayout({ groupHeaderPosition: "top" });
      
              // Add the following two lines of code.
              listView.itemTemplate = multisizeItemTemplateRenderer;
              listView.layout = new ui.GridLayout({ groupInfo: groupInfo, groupHeaderPosition: "top" });
          }
      },
      
    2. Remova a linha que atribui um modelo de item ao ListView e faça as mudanças indicadas pelos comentários nesse código.

      ready: function (element, options) {
          var listView = element.querySelector(".groupeditemslist").winControl;
      
          // Add the next line of code to retrieve the item template. 
          var itemTemplate = element.querySelector(".itemtemplate");
      
          listView.groupHeaderTemplate = element.querySelector(".headerTemplate");
      
          listView.oniteminvoked = this.itemInvoked.bind(this);
              listView.itemTemplate = element.querySelector(".itemtemplate");
      
          // Change the last argument of the _initializeLayout function to itemTemplate.
          this._initializeLayout(listView, appView.value, itemTemplate);
          listView.element.focus();
       },
      
      // This function updates the page layout in response to viewState changes.
      updateLayout: function (element, viewState, lastViewState) {
          var listView = element.querySelector(".groupeditemslist").winControl;
      
          // Add the next line of code to retrieve the item template.
          var itemTemplate = element.querySelector(".itemtemplate");
      
          if (lastViewState !== viewState) {
              if (lastViewState === appViewState.snapped || viewState === appViewState.snapped) {
                  var handler = function (e) {
                      listView.removeEventListener("contentanimating", handler, false);
                      e.preventDefault();
                  }
                  listView.addEventListener("contentanimating", handler, false);
      
                  // Change this line to pass through the item template.
                  this._initializeLayout(listView, viewState, itemTemplate);
              }
          }
      },
      
      
  6. Em seguida, precisamos adicionar estilo para os itens em groupedItems.css. Para estilizar os itens como mostra a imagem anterior, precisamos de 4 classes CSS para os 4 modelos de item diferentes na página de aterrissagem. Dê a essas 4 classes os seguintes nomes: smallitemtemplate, mediumitemtemplate, mediumlargeitemtemplate e largeitemtemplate. A próxima CSS posiciona em sua maior parte a sobreposição e o texto em relação à imagem e dimensiona cada item apropriadamente. Em alguns casos, certos elementos ficam recolhidos, porque nem todos os modelos usam todos os elementos no modelo de item. Adicione essa CSS logo antes da primeira linha CSS de @media screen.

    /* Generic styling */
    .groupeditemspage .groupeditemslist .item-overlay {
        -ms-grid-row: 2;
    }
    .groupeditemspage .groupeditemslist .item-overlay .item-description {
        visibility:collapse;
    }
    
    /* Small item template */
    .groupeditemspage .groupeditemslist .smallitemtemplate {
        width: 440px;
        height: 80px;
        overflow: hidden;
    
    }
    .groupeditemspage .groupeditemslist .smallitemtemplate .item-image {
        height: 80px;
        width: 80px;
    }
    .groupeditemspage .groupeditemslist .smallitemtemplate .item-overlay {
       opacity: 0;
    }
    .groupeditemspage .groupeditemslist .smallitemtemplate .item-overlay .item-title {
        position: absolute; 
        top: -5px;
        padding-left: 90px;
        font-size: 11pt;
    }
    .groupeditemspage .groupeditemslist .smallitemtemplate .item-overlay .item-subtitle {
        position: absolute; 
        top: 15px;
        padding-left: 90px;
        font-size: 9pt;
    }
    .groupeditemspage .groupeditemslist .smallitemtemplate .item-overlay .item-description {
        position: absolute; 
        top: 35px;
        padding-left: 90px;
        font-size: 9pt;
        visibility: visible;
        width: 360px;
        overflow-wrap: normal;
        text-overflow: initial;
    }
    
    /* Medium item template */
    .groupeditemspage .groupeditemslist .mediumitemtemplate {
        width: 260px;
        height: 170px;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 1fr 30px;
        display: -ms-grid;
        overflow: hidden;
    }      
    .groupeditemspage .groupeditemslist .mediumitemtemplate .item-overlay .item-title {
        padding-top: 5px;
        padding-left: 10px;
    }
    .groupeditemspage .groupeditemslist .mediumitemtemplate .item-overlay .item-title {
        font-size: 14px;
    }
    .groupeditemspage .groupeditemslist .mediumitemtemplate .item-overlay .item-subtitle {
        visibility: collapse;
    }   
    
    /* Medium-large item template */
    .groupeditemspage .groupeditemslist .mediumlargeitemtemplate {
        width: 260px;
        height: 350px;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 1fr 30px;
        display: -ms-grid;
        overflow: hidden;
    }
    .groupeditemspage .groupeditemslist .mediumlargeitemtemplate .item-overlay .item-title {
        padding-top: 5px;
        padding-left: 10px;
        font-size: 14px;
    }
    
    .groupeditemspage .groupeditemslist .mediumlargeitemtemplate .item-overlay .item-subtitle {
        visibility: collapse;
    }   
    
    /* Large item template */
    .groupeditemspage .groupeditemslist .largeitemtemplate {
        width: 440px;
        height: 530px;
        overflow: hidden;
        -ms-grid-columns: 1fr;
        -ms-grid-rows: 1fr 90px;
        display: -ms-grid;
    }
    .groupeditemspage .groupeditemslist .largeitemtemplate .item-overlay {
        -ms-grid-row: 2;
        -ms-grid-rows: 1fr 21px;
        display: -ms-grid;
        padding: 6px 15px 2px 15px;
    }
    .groupeditemspage .groupeditemslist .largeitemtemplate .item-subtitle{
        -ms-grid-row: 2;
    }
    
    
  7. Na regra @media screen and (-ms-view-state: fullscreen-landscape), screen and (-ms-view-state: fullscreen-portrait), screen and (-ms-view-state: filled), mude o primeiro estilo CSS para o seguinte. Esse código CSS torna a sobreposição opaca e remova a classe "item".

     .groupeditemspage .groupeditemslist .item-overlay {
            background: rgba(0,0,0,1);
        }
    
  8. Mude o primeiro estilo .groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface em groupedItems.css para isto.

        .groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface {
            margin-bottom: 60px;
            margin-left: 45px;
            margin-right: 115px;
        }
    

    Esse código CSS muda a margem inferior para "50px" para levar em consideração itens que são um pouco maiores.

Depois de fazer essas mudanças, inicie seu aplicativo. Ele terá a seguinte aparência:

O aplicativo atualizado

Adicione imagens, mude o plano de fundo, o texto e a cor de sobreposição, e você terá a página de aterrissagem do Trailer de Lances Contoso.

Tamanhos e modelos mais criativos

Há várias outras maneiras de personalizar seus modelos de itens além das que mostramos aqui. Por exemplo, essa página de aterrissagem tem uma aparência equilibrada usando dois tamanhos de item e três modelos diferentes.

Outra página de aterrissagem personalizada

A unidade base dessa página de destino é o tamanho do menor dos itens. O primeiro item em cada grupo tem 2x3 unidades base e um modelo que coloca o título e a descrição abaixo da imagem. Os próximos itens do grupo têm 1x1 unidades e sobrepõem o título e a descrição na imagem. O terceiro modelo é para itens que não têm imagens.

Adicionando animações de itens ListView

Na tela inicial, blocos dinâmicos apresentam ao usuário imagens e textos atuais que fornecem informações de imediato. A página de aterrissagem de um aplicativo pode fazer o mesmo, se apropriado, usando a Biblioteca de Animação WinJS.

Este exemplo faz com que o primeiro item da página de aterrissagem seja atualizado com uma nova imagem a cada 4 segundos, o mesmo tempo usado na tela inicial. Nós usamos a animação de relance WinJS, que é a mesma usada pelos blocos na tela inicial.

  1. No Visual Studio, crie um novo aplicativo que use o modelo Grid App.

  2. Em groupedItems.html, modifique o modelo de item de forma a incluir uma segunda imagem, que será usada para a animação.

        <div class="itemtemplate" data-win-control="WinJS.Binding.Template">
            <div class="item">
                <img class="item-image" src="#" data-win-bind="src: backgroundImage; alt: title" />
                <img class="item-image-new" 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>
    
  3. Em groupedItems.css, modifique a CSS de forma a posicionar a segunda imagem abaixo da imagem inicial. Isso nos permite animar a nova imagem no local, começando pela parte inferior do item. Precisamos fazer com que ambos os itens usem o posicionamento relativo, para podermos mudar suas posições antes de iniciar a animação. O primeiro e o terceiro estilos de CSS já existem em groupedItems.css e só precisam ser modificados. O segundo estilo de CSS é novo.

            /* Update this CSS style. */
            .groupeditemspage .groupeditemslist .item .item-image {
                -ms-grid-row-span: 2;
                position:relative;
            }
    
            /* Add this CSS style. */
            .groupeditemspage .groupeditemslist .item .item-image-new {
                -ms-grid-row-span: 2;
                position:relative;
                top: 250px;
            }
    
            /* Update this CSS style. */
            .groupeditemspage .groupeditemslist .item .item-overlay {
                -ms-grid-row: 2;
                -ms-grid-rows: 1fr 21px;
                display: -ms-grid;
                padding: 6px 15px 2px 15px;
                position:relative;
            }
    
  4. Em groupedItems.js, adicione este código à função ready para disparar uma nova animação de item a cada 4 segundos.

                setInterval(function () { changeImage() } , 4000);
    
  5. Em groupedItems.js, adicione este código fora da definição da página. As primeiras definições de variável apontam para as diferentes imagens usadas pelo modelo Grid App. Adicione a função peekTile para reproduzir a animação de relance da Biblioteca do Windows para JavaScript. Adicione a função changeImage para atualizar as imagens antes de reproduzir a animação. Neste exemplo, reproduzimos a animação somente para o primeiro item em ListView.

        // Define images
        var darkGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY3B0cPoPAANMAcOba1BlAAAAAElFTkSuQmCC";
        var lightGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY7h4+cp/AAhpA3h+ANDKAAAAAElFTkSuQmCC";
        var mediumGray = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXY5g8dcZ/AAY/AsAlWFQ+AAAAAElFTkSuQmCC";
    
        // Play the Peek animation
        function peekTile(tile1, tile2) {
            // Create peek animation
            var peekAnimation = WinJS.UI.Animation.createPeekAnimation([tile1, tile2]);
    
            // Reposition tiles to their desired post-animation position
            tile1.style.top = "-250px";
            tile2.style.top = "0px";
    
            // Execute animation
            peekAnimation.execute();
        }
    
       function changeImage() {
            // Get the two image elements
            var images = document.querySelector(".item-image");
            var imagesNew = document.querySelector(".item-image-new"); 
    
            // Swap out the old image source and choose the new image source
            images.src = imagesNew.src;
            if (images.src == lightGray)
                imagesNew.src = mediumGray;
            else if (images.src == mediumGray)
                imagesNew.src = darkGray;
            else
                imagesNew.src = lightGray;
    
            // Reset the elements for the pre-animation position and trigger the animation
            images.style.top = "0px";
            imagesNew.style.top = "250px";
            peekTile(images, imagesNew);
        };
    

    Parabéns, você adicionou animações de item personalizadas ao seu ListView!

Tópicos relacionados

ListView

Guia de início rápido: adicionando um ListView

Estilizando a ListView e seus itens