Comment personnaliser un contrôle ListView
[ Cet article est destiné aux développeurs Windows 8.x et Windows Phone 8.x qui créent des applications Windows Runtime. Si vous développez une application pour Windows 10, voir la Documentation ]
Dans Personnalisation d’applications du Windows Store, nous vous avions indiqué comment incorporer l’esprit de votre marque dans votre application en vous conformant aux principes de conception Microsoft. Nous avons abordé sept aspects de la conception d’une marque : couleur, icônes, images, grille, disposition, logo et typographie.
Dans cette rubrique, nous allons vous indiquer comment personnaliser la page d’accueil de votre application en employant les techniques suivantes :
- Modification des modèles d’élément ListView
- Modification de la taille des éléments ListView
- Ajout d’animations d’élément ListView
Cette rubrique vous indique comme modifier le modèle Application grille de Visual Studio pour créer des pages d’accueil comme celles présentées ci-dessous :
Prérequis
- Nous partons du principe que vous connaissez les principes de base pour incorporer votre marque dans votre application comme il est indiqué dans Personnalisation d’applications du Windows Store.
- Nous partons du principe que vous savez créer et utiliser un objet ListView élémentaire. Pour une présentation du contrôle ListView, voir Démarrage rapide : ajout d’un contrôle ListView.
Quand utiliser un contrôle ListView
Vous devez d’abord décider quels contrôles vous allez utiliser dans votre page d’accueil. Pour obtenir une liste des contrôles HTML et de la Bibliothèque Windows pour JavaScript, voir la liste des contrôles.
Si vous souhaitez présenter un ensemble de données sous la forme d’une série d’éléments, comme une liste de publipostage, les résultats d’une recherche ou un catalogue d’éléments, utilisez un contrôle ListView.
Le contrôle ListView affiche les éléments dans une liste ou une grille. La plupart des pages d’accueil qui affichent des éléments utilisent la disposition en grille du contrôle ListView, car elle dispose automatiquement les éléments horizontalement. Pour personnaliser les éléments dans le contrôle ListView, il vous suffit de modifier le itemTemplate utilisé pour afficher les éléments.
La disposition en grille CSS3 et le système de grille de Windows 8
L’aspect de Windows 8 repose en grande partie sur le système de grille, car il garantit l’homogénéité visuelle des applications et de leurs fonctionnalités. La disposition en grille vous permet de répartir les éléments sur la page et de les aligner facilement dans la grille.
Dans nos exemples, nous utilisons également la disposition en grille CSS3 (Cascading Style Sheets, niveau 3) qui est différente de la disposition en grille du contrôle ListView. La disposition en grille CSS3 permet une stylisation standard pour de nombreuses utilisations, tandis que le contrôle ListView sert uniquement à la présentation d’ensembles de données. Avec la disposition en grille CSS3, vous pouvez disposer proprement les éléments de vos applications en les alignant facilement dans la grille.
Exemple de la boulangerie Contoso French Bakery
Examinons le modèle Grid App de Visual Studio par défaut et comparons-le à l’exemple Contoso French Bakery de la rubrique Personnalisation d’applications du Windows Store. Voici une capture d’écran du modèle Grid App :
Comparons cette capture d’écran à la page d’accueil de Contoso French Bakery de la rubrique Personnalisation d’applications du Windows Store. Les éléments de la page d’accueil de Contoso French Bakery sont disposés de manière à mettre en valeur la marque Contoso.
Bien que l’aspect de la page d’accueil de Contoso French Bakery soit très différent de celui de la page créée avec le modèle Grid App, la différence est due simplement à quelques modifications HTML/CSS. Dans cet exemple, nous partons du principe que les éléments sont interactifs et qu’en sélectionnant un élément, l’utilisateur accède à une page de détail de groupe présentant différents types de macarons, de cupcakes, etc. Un contrôle ListView qui utilise la disposition en grille est approprié pour cette page d’accueil.
Pour convertir le modèle Grid App en page d’accueil de Contoso, nous devons modifier la taille des modèles d’élément, augmenter celle des images et ajouter des descriptions d’élément.
Dans Visual Studio, nous créons une nouvelle application qui utilise le modèle Grid App.
Nous mettons à jour le
itemtemplate
HTML dans groupedItems.html. La principale modification apportée auitemtemplate
par défaut consiste à ajouter un troisième élément d’en-tête pour afficher la description de chaque élément.<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>
Nous devons maintenant mettre à jour les styles dans groupedItems.css. La principale modification de groupedItems.css consiste à déplacer le texte div sous l’image, au lieu de le placer sur l’image, et à ajouter une ligne à la grille pour les détails de l’élément.
.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; }
Nous supprimons les en-têtes des groupes de data.js. (Pour cela, il suffit simplement de supprimer le titre de chaque groupe).
Avec ces modifications, votre application se présente comme suit :
Ajoutez des images et changez l’arrière-plan et le titre, et vous avez créé la page d’accueil de Contoso French Bakery !
Exemple de la page d’accueil des camions-restaurants Contoso
Dans l’exemple suivant, nous créons la page d’accueil des camions-restaurants Contoso à partir du modèle Grid App.
La page d’accueil des camions-restaurants Contoso éveille l’intérêt de l’utilisateur avec des images attrayantes de tailles différentes.
Contrairement à l’exemple précédent, cette page d’accueil requiert des ajouts JavaScript au modèle, principalement pour ajouter la logique permettant de donner différentes tailles aux éléments dans le contrôle ListView. De nouveau, nous partons du principe que les éléments de la page d’accueil sont interactifs et qu’en sélectionnant un élément, l’utilisateur accède à une vue détaillant cet élément. Un contrôle ListView qui utilise la disposition en grille est l’outil approprié pour cette tâche. Nous utilisons de nouveau le modèle Grid App comme point de départ.
Pour utiliser des éléments de différentes tailles, nous devons d’abord définir une unité de base minimale. Cette unité servira à créer tous les éléments de la grille. Tous les éléments de la grille doivent être composés de multiples de cette unité. La plus petite dimension de l’un des éléments dans l’image suivante est la hauteur des éléments dans la section « Near Me » (Près de chez moi), qui est d’environ 80px. La dimension horizontale offre plus de flexibilité. Pour plus de simplicité, nous utilisons également 80px comme unité pour la dimension horizontale.
Cette image montre à quoi ressemble l’unité de base (le carré rouge) par rapport à plusieurs éléments.
Pour calculer la taille des éléments, celle-ci doit être égale à un multiple de l’unité de base, plus le remplissage entre les unités. La formule est la suivante :
item sizeₓ = m * base unit sizeₓ + (m -1) * item paddingₓ
item sizey = m * base unit sizey + (m -1) * item paddingy
où m est un entier positif, et x et y indiquent les dimensions x et y de l’élément et son remplissage.
Si la taille de base des éléments est trop petite, cela nuira aux performances de votre application. En règle générale, la taille d’un élément ne doit pas faire plus de quelques unités de base dans chaque direction.
Dans Visual Studio, nous créons une nouvelle application qui utilise le modèle Grid App.
Dans groupedItems.html, nous créons un nouveau modèle d’élément nommé
multisizebaseitemtemplate
. Ce modèle d’élément est plus ou moins le même que le modèle par défaut, mais nous y ajoutons un en-tête « item-description » pour pouvoir inclure la description de l’élément en plus du titre et du sous-titre sur la page d’accueil.<!-- 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>
Dans groupedItems.js, nous créons une fonction de création de modèle nommée
multisizeItemTemplateRenderer
avant la définition PageControl (ui.Pages.define
).Nous utilisons cette fonction pour rendre les éléments ListView. C’est cette fonction qui détermine quel modèle d’élément est utilisé par quels éléments. Nous allons l’attribuer à la propriété itemTemplate du contrôle ListView à une étape ultérieure.
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; }); }
Dans groupedItems.js, ajoutez la fonction
groupInfo
ci-dessous, également en dehors de la définition de page. Cette fonction indique au contrôle ListView de faire appel à des éléments de taille différente dans l’affichage, et indique la taille de base des éléments. La taille de base représente le plus petit élément repris dans la liste. Les autres éléments doivent adopter une taille correspondant à un multiple de cette taille pour que les dispositions fonctionnent correctement.function groupInfo() { return { enableCellSpanning: true, cellWidth: 80, cellHeight: 80 }; }
Nous devons maintenant ajouter ces nouvelles fonctions au contrôle ListView.
Dans le fichier groupedItems.js, modifiez la fonction
_initializeLayout
de sorte qu’une simple liste de groupes s’affiche.// 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" }); } },
Nous supprimons la ligne qui attribue un modèle d’élément au contrôle ListView et nous apportons les modifications indiquées par les commentaires dans le code suivant.
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); } } },
Ensuite, nous devons ajouter la stylisation des éléments à groupedItems.css. Pour styliser les éléments comme dans l’image précédente, nous avons besoin de 4 classes CSS pour les 4 modèles d’élément différents sur la page d’accueil. Nous nommons les 4 classes
smallitemtemplate
,mediumitemtemplate
,mediumlargeitemtemplate
etlargeitemtemplate
. Le code CSS suivant positionne principalement la superposition et le texte par rapport à l’image et dimensionne chaque élément comme il convient. Dans certains cas, des éléments sont réduits, car tous les modèles n’utilisent pas tous les éléments dans le modèle d’élément. Nous ajoutons ce code CSS juste avant la première ligne CSS@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; }
Dans la règle
@media screen and (-ms-view-state: fullscreen-landscape), screen and (-ms-view-state: fullscreen-portrait), screen and (-ms-view-state: filled)
, nous modifions le premier style CSS comme il est indiqué ci-dessous. Ce code CSS rend opaque la superposition et supprime la classe "item"..groupeditemspage .groupeditemslist .item-overlay { background: rgba(0,0,0,1); }
Nous modifions le premier style
.groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface
dans groupedItems.css comme suit..groupeditemspage .groupeditemslist .win-horizontal.win-viewport .win-surface { margin-bottom: 60px; margin-left: 45px; margin-right: 115px; }
Ce code CSS définit « margin-bottom » sur "50px" pour prendre en compte des éléments légèrement plus grands.
Une fois toutes ces modifications apportées, lancez l’application. Elle se présente comme suit :
Ajoutez des images, changez l’arrière-plan, le texte et la couleur de la superposition et vous obtenez la page d’accueil des camions-restaurants Contoso.
Autres tailles et modèles pour plus de créativité
Il existe d’autres moyens de personnaliser vos modèles d’élément que ceux que nous vous avons présentés ici. Par exemple, cette page d’accueil obtient un aspect équilibré grâce à deux tailles d’éléments et trois modèles différents.
L’unité de base de cette page d’accueil est la taille du plus petit élément. Le premier élément de chaque groupe est constitué d’unités de base sous la forme 2x3 et a un modèle qui place le titre et la description sous l’image. Les éléments suivants dans le groupe sont des unités 1x1 et placent le titre et la description sur l’image. Le troisième modèle est destiné aux éléments sans image.
Ajout d’animations d’élément ListView
Dans l’écran d’accueil, des vignettes dynamiques présentent à l’utilisateur des images et du texte qui fournissent des informations récentes en un coup d’œil. La page d’accueil d’une application peut faire la même chose, le cas échéant, à l’aide de la Bibliothèque d’animations WinJS.
Dans cet exemple, le premier élément sur la page d’accueil est mis à jour avec une nouvelle image toutes les 4 secondes, soit le même laps de temps que sur l’écran d’accueil. Nous utilisons l’animation synoptique WinJS, qui est la même animation que celle utilisée pour les vignettes de l’écran d’accueil.
Dans Visual Studio, nous créons une nouvelle application qui utilise le modèle Grid App.
Dans groupedItems.html, nous modifions le modèle d’élément pour qu’il comporte une seconde image, qui sera utilisée pour l’animation.
<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>
Dans groupedItems.css, nous modifions le code CSS pour placer la seconde image sous l’image initiale. Cela nous permet de placer la nouvelle image en partant du bas de l’élément. Nous devons faire en sorte que les deux éléments utilisent un positionnement relatif pour pouvoir changer leur position avant de lancer l’animation. Les premier et troisième styles CSS existent déjà dans groupedItems.css et il suffit simplement de les modifier. Le deuxième style CSS est nouveau.
/* 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; }
Dans groupedItems.js, nous ajoutons ce code à la fonction ready pour déclencher une nouvelle animation d’élément toutes les 4 secondes.
setInterval(function () { changeImage() } , 4000);
Dans groupedItems.js, nous ajoutons ce code en dehors de la définition de page. Les premières définitions de variable pointent vers les différentes images utilisées par le modèle Grid App. Nous ajoutons la fonction
peekTile
pour lancer l’animation synoptique de la Bibliothèque Windows pour JavaScript. Nous ajoutons la fonctionchangeImage
pour mettre à jour les images avant de lancer l’animation. Dans cet exemple, nous lançons l’animation uniquement pour le premier élément dans le contrôle 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); };
Des animations d’élément personnalisé sont ajoutées au contrôle ListView !