다음을 통해 공유


ListView를 브랜딩하는 방법

[ 이 문서는 Windows 런타임 앱을 작성하는 Windows 8.x 및 Windows Phone 8.x 개발자를 대상으로 합니다. Windows 10용으로 개발하는 경우에는 최신 설명서를 참조하세요.]

Windows 스토어 앱 브랜딩에서는 Microsoft 디자인 원칙을 준수하는 동시에 브랜드 본질을 앱에 통합하는 방법에 대해 설명했습니다. 색, 아이콘, 이미지, 그리드, 레이아웃, 로고, 입력 체계 등 브랜드 디자인의 여러 측면을 다루었습니다.

여기서는 다음 기술을 사용하여 앱의 방문 페이지를 사용자 지정하는 방법에 대해 설명합니다.

이 항목에서는 Visual Studio 그리드 앱 템플릿에서 시작하고 다음과 같이 수정하여 방문 페이지를 만드는 방법을 보여 줍니다.

Contoso Bakery 방문 페이지

Contoso Food Truck 예제

사전 요구 사항

ListView를 사용해야 하는 경우

먼저 방문 페이지에서 사용할 컨트롤을 결정해야 합니다. HTML 및 JavaScript용 Windows 라이브러리 컨트롤 목록은 컨트롤 목록을 참조하세요.

메일 목록, 검색 결과, 구매용 항목 카탈로그 등 일련의 항목으로 데이터 수집을 제공하려는 경우 ListView를 사용합니다.

ListView는 항목을 목록이나 그리드 레이아웃으로 표시합니다. 항목을 표시하는 방문 페이지는 대부분 ListView 컨트롤의 그리드 레이아웃을 사용합니다. 이 레이아웃은 자동으로 오버플로되고 가로로 스크롤되기 때문입니다. 항목을 표시하는 데 사용되는 itemTemplate을 수정하여 ListView의 항목을 사용자 지정할 수 있습니다.

CSS3 그리드 레이아웃 및 Windows 8 그리드 시스템

그리드 시스템은 Windows 8 모양과 느낌의 중요한 부분이며 여러 앱과 기능에서 시각적 통일성을 얻는 데 도움이 됩니다. 그리드 레이아웃을 사용할 경우 페이지에 요소 공간을 나누고 쉽게 요소를 그리드에 맞출 수 있습니다.

예제에서는 ListView 컨트롤의 그리드 레이아웃과 다른 CSS3(CSS 스타일시트, Level 3) 그리드 레이아웃도 사용합니다. CSS3 그리드 레이아웃은 다양한 사용을 위해 범용 그리드 스타일 지정을 제공하는 반면, ListView는 데이터 수집을 표시하는 데만 사용됩니다. CSS3 그리드 레이아웃을 사용할 경우 앱을 깔끔하게 레이아웃하고 요소를 쉽게 그리드에 맞출 수 있습니다.

Contoso French Bakery 예제

기본 Visual Studio Grid App 템플릿을 살펴보고 Windows 스토어 앱 브랜딩의 Contoso French Bakery 예제와 비교해 보겠습니다. 다음은 Grid App 템플릿의 스크린샷입니다.

그리드 앱 템플릿을 사용한 앱

이 템플릿을 Windows 스토어 앱 브랜딩의 Contoso French Bakery 방문 페이지와 비교해 보겠습니다. Contoso French Bakery는 Contoso 브랜드를 강조하는 사용자 지정 방식으로 항목을 레이아웃합니다.

Contoso Bakery 방문 페이지

Contoso French Bakery 방문 페이지는 Grid App 템플릿과 전혀 다르게 표시되지만 이 차이는 단지 몇 개의 HTML/CSS를 수정한 결과입니다. 이 예제에서는 항목이 인터랙티브이며 항목을 선택할 경우 마카롱, 컵케이크 등의 유형을 선택할 수 있는 그룹 세부 정보 페이지가 사용자에게 표시된다고 가정합니다. 그리드 레이아웃을 사용하는 ListView가 이 방문 페이지에 적합한 컨트롤입니다.

Grid App 템플릿을 Contoso 방문 페이지로 변환하려면 항목 템플릿의 크기를 변경하고, 이미지 크기를 늘리고, 항목 설명을 추가해야 합니다.

  1. Visual Studio에서 Grid App 템플릿을 사용하는 새 앱을 만듭니다.

  2. groupedItems.html에서 HTML itemtemplate을 업데이트합니다. 기본 itemtemplate에서의 주요 변경 내용은 각 항목 설명을 표시할 세 번째 제목 요소를 추가하는 것입니다.

        <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. 이제 groupedItems.css에서 스타일을 업데이트합니다. groupedItems.css에서의 주요 변경 내용은 텍스트 div를 이미지 위에 오버레이하는 대신 이미지 아래로 이동하고 항목 세부 정보 요소를 위해 그리드에 다른 행을 추가하는 것입니다.

    .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. data.js에서 그룹 헤더를 제거합니다. 가장 쉬운 방법은 단순히 각 그룹의 제목을 삭제하는 것입니다.

이렇게 변경하면 앱이 다음과 같이 표시됩니다.

업데이트된 앱

일부 이미지를 추가하고 배경과 제목을 변경하면 Contoso French Bakery 방문 페이지가 만들어집니다.

Contoso Food Truck 예제

다음 예제에서는 Grid App 템플릿에서 Contoso Food Truck 방문 페이지를 만듭니다.

Contoso Food Truck 예제

Contoso Food Truck 방문 페이지에서는 다양한 크기의 멋진 이미지로 사용자의 관심을 끕니다.

이전 예제와 달리 이 방문 페이지에서는 주로 ListView의 항목에 서로 다른 크기를 제공하는 논리를 추가하기 위해 템플릿에 JavaScript를 추가해야 합니다. 여기서도 방문 페이지의 항목은 인터랙티브이며 항목을 선택할 경우 해당 항목의 세부 정보 보기가 사용자에게 표시된다고 가정합니다. 그리드 레이아웃을 사용하는 ListView가 작업에 적합한 도구입니다. 다시 Grid App 템플릿을 시작 지점으로 사용합니다.

여러 크기의 항목을 사용하려면 먼저 최소 기본 단위를 결정해야 합니다. 이 단위를 사용하여 그리드 항목을 모두 빌드하므로 모든 그리드 항목은 이 그리드 크기의 배수로 구성되어야 합니다. 다음 이미지에 있는 항목 중 하나의 가장 작은 크기는 "주변" 섹션의 항목 높이로, 약 80px입니다. 가로 크기는 유연성이 더 큽니다. 간단한 설명을 위해 가로 크기에도 80px를 사용합니다.

이 이미지는 여러 실제 항목과 비교하여 기본 단위(빨간색 사각형)가 어떻게 표시되는지를 보여 줍니다.

기본 항목 크기

항목 크기를 계산할 때 각 항목 크기는 기본 단위의 배수와 단위 사이의 안쪽 여백 합계와 같아야 합니다. 공식은 다음과 같습니다.

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

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

여기서 m은 양의 정수이고 x 및 y는 항목 크기와 항목 안쪽 여백의 x 및 y 크기를 나타냅니다.

기본 크기가 항목과 비교해서 너무 작으면 앱의 성능이 저하됩니다. 대체로 항목 크기는 임의 방향의 몇 개 기본 단위를 넘지 않아야 합니다.

  1. Visual Studio에서 Grid App 템플릿을 사용하는 새 앱을 만듭니다.

  2. groupedItems.html에서 multisizebaseitemtemplate이라는 새 항목 템플릿을 만듭니다. 이 항목 템플릿은 대체로 기본 항목 템플릿과 동일하지만 "item-description" 헤더가 추가되어 있으므로 방문 페이지에 제목 및 부제와 함께 항목 설명을 포함할 수 있습니다.

      <!-- 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. groupedItems.js에서 PageControl 정의(ui.Pages.define) 앞에 multisizeItemTemplateRenderer라는 템플릿 함수를 만듭니다.

    이 함수를 사용하여 ListView 항목을 렌더링합니다. 각 항목이 사용하는 항목 템플릿을 결정하는 것은 이 함수입니다. 이후 단계에서 ListView 컨트롤의 itemTemplate 속성에 이 함수를 할당합니다.

     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. groupedItems.js에서 groupInfo 함수도 페이지 정의 바깥쪽에 추가합니다. 이 함수는 보기에서 여러 크기의 항목을 사용하도록 ListView에 지정하고 항목의 기본 크기를 나타냅니다. 기본 크기는 목록에 표시된 가장 작은 항목입니다. 레이아웃이 제대로 작동하려면 다른 항목 크기가 이 크기의 배수여야 합니다.

     function groupInfo() {
        return {
            enableCellSpanning: true,
            cellWidth: 80,
            cellHeight: 80
        };
     }
    
  5. 이제 새 함수를 ListView 컨트롤까지 연결해야 합니다.

    1. groupedItems.js에서 그룹의 단순 목록을 표시하도록 _initializeLayout 함수를 변경합니다.

      // 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. 이 코드에서 ListView에 항목 템플릿을 할당하는 줄을 제거하고 주석에 표시된 대로 변경합니다.

      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. 다음에는 항목의 스타일 지정을 groupedItems.css에 추가해야 합니다. 이전 이미지에 표시된 대로 항목에 스타일을 지정하려면 방문 페이지의 4가지 항목 템플릿에 대한 CSS 클래스 4개가 필요합니다. 4개 클래스에 smallitemtemplate, mediumitemtemplate, mediumlargeitemtemplatelargeitemtemplate이라는 이름을 지정합니다. 다음 CSS는 대체로 이미지를 기준으로 오버레이와 텍스트를 배치하고 각 항목의 크기를 적절하게 지정합니다. 항목 템플릿의 일부 요소를 사용하지 않는 템플릿도 있으므로 경우에 따라 특정 요소는 축소됩니다. 첫 번째 @media screen CSS 줄 바로 앞에 이 CSS를 추가합니다.

    /* 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. @media screen and (-ms-view-state: fullscreen-landscape), screen and (-ms-view-state: fullscreen-portrait), screen and (-ms-view-state: filled) 규칙에서 첫 번째 CSS 스타일을 다음과 같이 변경합니다. 이 CSS 코드는 오버레이를 불투명하게 만들고 "item" 클래스를 제거합니다.

     .groupeditemspage .groupeditemslist .item-overlay {
            background: rgba(0,0,0,1);
        }
    
  8. groupedItems.css에서 첫 번째 .groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface 스타일을 다음과 같이 변경합니다.

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

    이 CSS 코드는 약간 더 큰 항목을 포함하기 위해 margin-bottom을 "50px"로 변경합니다.

이러한 변경 작업이 끝나면 앱을 시작합니다. 앱이 다음과 같이 표시됩니다.

업데이트된 앱

사진을 추가하고 배경, 텍스트 및 오버레이 색을 변경하면 Contoso Food Truck 방문 페이지가 만들어집니다.

보다 독창적인 크기 및 템플릿

항목 템플릿을 사용자 지정하는 방법은 여기에 표시된 것보다 더 많습니다. 예를 들어 두 가지 항목 크기와 세 가지 템플릿을 사용하여 이 방문 페이지를 균형 있는 모양으로 수정할 수 있습니다.

다른 사용자 지정 방문 페이지

이 방문 페이지의 기본 단위는 가장 작은 항목의 크기입니다. 각 그룹에서 첫 번째 항목은 2x3 기본 단위이고 제목과 설명을 이미지 아래에 배치하는 템플릿을 사용합니다. 그룹에서 다음 항목은 1x1 단위이고 제목과 설명을 이미지 위에 오버레이합니다. 세 번째 템플릿은 이미지가 없는 항목에 사용됩니다.

ListView 항목 애니메이션 추가

시작 화면에서 라이브 타일은 최신 사진과 한눈에 정보를 제공하는 텍스트를 사용자에게 표시합니다. 필요한 경우 앱의 방문 페이지도 WinJS 애니메이션 라이브러리를 사용하여 동일한 기능을 수행할 수 있습니다.

이 예제에서는 방문 페이지의 첫 번째 항목이 4초마다 새 이미지로 업데이트되도록 합니다. 시작 화면에서도 동일한 시간이 사용됩니다. 시작 화면의 타일에 사용되는 것과 동일한 애니메이션인 WinJS peek 애니메이션을 사용합니다.

  1. Visual Studio에서 Grid App 템플릿을 사용하는 새 앱을 만듭니다.

  2. groupedItems.html에서 애니메이션에 사용할 두 번째 이미지를 포함하도록 항목 템플릿을 수정합니다.

        <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. groupedItems.css에서 CSS를 수정하여 두 번째 이미지를 초기 이미지 아래에 배치합니다. 이렇게 하면 항목 아래에서 시작하여 제자리까지 새 이미지에 애니메이션 효과를 줄 수 있습니다. 애니메이션을 시작하기 전에 위치를 변경할 수 있도록 두 항목이 모두 상대 위치를 사용하도록 해야 합니다. 첫 번째 및 세 번째 CSS 스타일은 groupedItems.css에 이미 있으며 수정하기만 하면 됩니다. 두 번째 CSS 스타일은 새로 추가된 것입니다.

            /* 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. groupedItems.js에서 다음 코드를 ready 함수에 추가하여 새 항목 애니메이션을 4초마다 트리거합니다.

                setInterval(function () { changeImage() } , 4000);
    
  5. groupedItems.js에서 다음 코드를 페이지 정의 바깥쪽에 추가합니다. 첫 번째 변수 정의는 Grid App 템플릿에서 사용되는 각기 다른 이미지를 가리킵니다. peekTile 함수를 추가하여 JavaScript용 Windows 라이브러리 peek 애니메이션을 재생합니다. changeImage 함수를 추가하여 애니메이션을 재생하기 전에 이미지를 업데이트합니다. 이 예제에서는 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);
        };
    

    축하합니다. ListView에 사용자 지정 항목 애니메이션을 추가했습니다.

관련 항목

ListView

빠른 시작: ListView 추가

ListView 및 관련 항목 스타일 지정