Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Modifier le rendu des listes

Compatible Flex 3. Cliquer pour en savoir plus sur les compatibilités.Par tannoy (Antony Chauviré), le 03 février 2010

Introduction

Flex propose des contrôles nous permettant d’afficher des listes de données. Ces contrôles permettent à l’utilisateur de défiler à travers les données et d’en sélectionner une ou plusieurs.

Les composants de types listes, dérivent tous de la classe ListBase et on retrouve parmi eux les contrôles suivants :

  • List
  • HorizontalList
  • TileList
  • Menu
  • MenuBar
  • Tree
  • DataGrid

Ces contrôles obtiennent leurs données depuis un data provider. Ce fournisseur de données est une collection contenant un objet de type Array ou XML.

Plusieurs contrôles peuvent utiliser le même fournisseur de données.

Les collections principales de Flex sont les classes ArrayCollection et XMLListCollection.

Le mode de rendu par défaut

Pour afficher les données, les contrôles de types listes utilisent ce que l’on appelle des item renderer. Les contrôles List et HorizontalList utilisent par défaut la classe ListItemRenderer, qui permet d’afficher un texte et éventuellement une image.

On pourra préciser quelles données du data provider doivent être utilisées pour l’affichage en renseignant les propriétés labelField et iconField du contrôle.

default_item_renderer.jpg

Dans notre exemple, nous allons utiliser des données créées grâce à une classe personnalisée que j'ai appelée Icon. Les objets de type Icon possèderont un nom, un prix, une taille et un chemin vers l'image.

package fr.tannoy.model
{
	public class Icon
	{
		public function Icon(name:String = "icon", price:Number = 0.00, size:String = "128", pathImage:String = "")
		{
			this.name = name;
			this.price = price;
			this.size = size;
			this.pathImage = pathImage;
		}
 
 
		private var _name:String = "icon";
		public function get name():String
		{
			return _name;
		}
		public function set name(value:String):void
		{
			_name = value.toUpperCase();
		}
 
		private var _price:Number = 0.00;
		public function get price():Number
		{
			return _price;
		}
		public function set price(value:Number):void
		{
			_price = value;
		}
 
		private var _size:String = "128 x 128";
		public function get size():String
		{
			return _size;
		}
		public function set size(value:String):void
		{
			_size = value + " x " + value;
		}
 
		private var _pathImage:String = "";
		public function get pathImage():String
		{
			return _pathImage;
		}
		public function set pathImage(value:String):void
		{
			_pathImage = value;
		}
	}
}

Nous indiquerons ensuite dans notre liste que nous souhaitons afficher le nom des icônes. Nous valoriserons la propriété labelField de notre liste avec la propriété name de notre objet Icon.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="creationCompleteHandler()">
 
	<mx:Script>
		<![CDATA[
			import fr.tannoy.model.Icon;
			import mx.collections.ArrayCollection;
 
			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection();
 
			private function creationCompleteHandler():void
			{
				dp.addItem(new Icon("Cinema Display", 1.20, "128", "assets/CinemaDisplay.png"));
				dp.addItem(new Icon("Monitor", 0.80, "128", "assets/desktop.png"));
				dp.addItem(new Icon("HP Monitor", 1.00, "128", "assets/HP-Monitor-Dock-512.png"));
				dp.addItem(new Icon("Macintosh", 1.40, "128", "assets/mymac.png"));
				dp.addItem(new Icon("LCD TV", 1.30, "128", "assets/nvtv.png"));
			}
		]]>
	</mx:Script>
 
	<mx:HorizontalList x="49" y="186" dataProvider="{dp}" labelField="name" height="52"></mx:HorizontalList>
	<mx:List x="49" y="22" dataProvider="{dp}" labelField="name" height="114"></mx:List>
 
</mx:Application>

Modifier le mode de rendu par défaut

Nous allons pouvoir contrôler l’affichage de nos listes en utilisant des item renderer personnalisés.

Il existe trois façons dans Flex pour définir un item renderer d’un contrôle :

  1. Item renderer de type “Drop-in” : utilisation d’un seul composant pour définir l’item renderer
  2. Item renderer de type “Inline” : utilisation de plusieurs composants pour définir l’item renderer
  3. Item renderer de type “Component” : utilisation d’un composant réutilisable pour définir l’item renderer

Item renderer de type Drop-in

Pour créer un item renderer simple, il suffit de définir la propriété itemRenderer d’un contrôle avec une valeur référençant la classe du contrôle que vous voulez utiliser pour le rendu.

itemRenderer="mx.controls.Image"

Dans l’exemple suivant, nous utilisons une Image comme item renderer et nous indiquons que c’est la propriété pathImage de nos objets Icon qui doit être utilisée dans notre item renderer.

drop_in_item_renderer.jpg

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                layout="absolute"
                creationComplete="creationCompleteHandler()">
 
	<mx:Script>
		<![CDATA[
			import fr.tannoy.model.Icon;
			import mx.collections.ArrayCollection;
 
			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection();
 
			private function creationCompleteHandler():void
			{
				dp.addItem(new Icon("Cinema Display", 1.20, "128", "assets/CinemaDisplay.png"));
				dp.addItem(new Icon("Monitor", 0.80, "128", "assets/desktop.png"));
				dp.addItem(new Icon("HP Monitor", 1.00, "128", "assets/HP-Monitor-Dock-512.png"));
				dp.addItem(new Icon("Macintosh", 1.40, "128", "assets/mymac.png"));
				dp.addItem(new Icon("LCD TV", 1.30, "128", "assets/nvtv.png"));
			}
		]]>
	</mx:Script>
 
	<mx:HorizontalList x="49" 
		y="186" 
		dataProvider="{dp}" 
		labelField="pathImage"
		itemRenderer="mx.controls.Image"
		columnWidth="128"
		rowHeight="128"
		height="150">
	</mx:HorizontalList>
	<mx:List x="49" y="22" dataProvider="{dp}" labelField="name" height="114"></mx:List>
 
</mx:Application>

Ce type d’item renderer permet donc de créer rapidement un rendu simple d’un contrôle. Il n’y a que les composants implémentant l’interface IDropInListItemRenderer qui peuvent être utilisés pour ce type d’item renderer.

Les contrôles suivants implémentent cette interface et peuvent donc être utilisés :

  • Button
  • CheckBox
  • DateField
  • Image
  • Label
  • NumericStepper
  • Text
  • TextArea
  • TextInput

Item renderer de type Inline

Ce type d’item renderer vous permet de créer un mode de rendu plus évolué. En effet, vous ne serez pas limité à l’utilisation d’un seul contrôle mais vous pourrez utiliser plusieurs contrôles et les configurer comme vous le souhaitez.

La valeur de l’item renderer ne sera pas défini en tant qu’attribut mais en utilisant des tags MXML imbriqués. Le premier d’entre eux sera le tag <mx :itemrenderer> à l’intérieur du quel nous insèrerons le tag <mx :Component>.

<mx:itemRenderer>
  <mx:Component>
 
  </mx:Component>
</mx:itemrenderer>

C’est dans ce dernier tag que nous viendrons insérer nos contrôles définissant le rendu. Dans l’exemple ci-dessous, nous allons utiliser une VBox contenant une image et un texte.

<mx:HorizontalList x="49" 
		y="186" 
		dataProvider="{dp}" 
		columnWidth="140"
		rowHeight="180"
		height="200">
		<mx:itemRenderer>
			<mx:Component>
				<mx:VBox horizontalAlign="center" verticalScrollPolicy="off" horizontalScrollPolicy="off">
					<mx:Image />
					<mx:Label />
				</mx:VBox>
			</mx:Component>
		</mx:itemRenderer>
	</mx:HorizontalList>

Pour que l’item renderer puisse utiliser et afficher les données de la liste, celle-ci lui passe l’objet du data provider, devant être rendu, dans sa propriété data. Dans notre cas, l’objet data de notre item renderer correspond à un objet Icon.

Nous pouvons donc ensuite indiquer que notre image doit utiliser la propriété pathImage et notre texte, la propriété name.

inline_item_renderer.jpg

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                layout="absolute"
                creationComplete="creationCompleteHandler()">
 
	<mx:Script>
		<![CDATA[
			import fr.tannoy.model.Icon;
			import mx.collections.ArrayCollection;
 
			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection();
 
			private function creationCompleteHandler():void
			{
				dp.addItem(new Icon("Cinema Display", 1.20, "128", "assets/CinemaDisplay.png"));
				dp.addItem(new Icon("Monitor", 0.80, "128", "assets/desktop.png"));
				dp.addItem(new Icon("HP Monitor", 1.00, "128", "assets/HP-Monitor-Dock-512.png"));
				dp.addItem(new Icon("Macintosh", 1.40, "128", "assets/mymac.png"));
				dp.addItem(new Icon("LCD TV", 1.30, "128", "assets/nvtv.png"));
			}
		]]>
	</mx:Script>
 
	<mx:HorizontalList x="49" 
		y="186" 
		dataProvider="{dp}" 
		columnWidth="140"
		rowHeight="180"
		height="200">
		<mx:itemRenderer>
			<mx:Component>
				<mx:VBox horizontalAlign="center" verticalScrollPolicy="off" horizontalScrollPolicy="off">
					<mx:Image source="{data.pathImage}" />
					<mx:Label text="{data.name}" />
				</mx:VBox>
			</mx:Component>
		</mx:itemRenderer>
	</mx:HorizontalList>
	<mx:List x="49" y="22" dataProvider="{dp}" labelField="name" height="114"></mx:List>
 
</mx:Application>

Item renderer de type Component

La problématique des deux types d’item renderer précédents est qu’ils ne sont pas réutilisables. En effet, ils sont liés aux composants dans lesquels ils sont définis.

Avec un item renderer de type Component, nous allons externaliser le rendu dans un composant MXML. Le composant pourra donc être utilisé par plusieurs contrôles de notre application.

component_item_renderer.jpg

Nous allons donc créer notre propre composant MXML que l'on appellera IconRenderer. Le fichier sera enregistré dans le chemin suivant fr\tannoy\renderers\IconRenderer.mxml.

Comme pour les itemRenderer de type inline, l'objet devant être rendu sera transmis dans la propriété data de notre itemRenderer.

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" 
	horizontalAlign="center" 
	horizontalScrollPolicy="off"
	verticalScrollPolicy="off" height="180">
	<mx:HBox>
		<mx:VBox horizontalAlign="center">
			<mx:Image source="{data.pathImage}" />
			<mx:Label text="{data.name}" />
		</mx:VBox>
		<mx:VBox verticalAlign="middle" horizontalAlign="center" height="180">
			<mx:HBox>
				<mx:Label text="Prix :" />
				<mx:Label text="{data.price}" />
			</mx:HBox>
			<mx:HBox>
				<mx:Label text="Taille :" />
				<mx:Label text="{data.size}" />
			</mx:HBox>
		</mx:VBox>
	</mx:HBox>
</mx:VBox>

Comme pour un item de type Drop-in, nous définiront la propriété itemRenderer d’un contrôle avec une valeur référençant la classe du composant que nous voulons utiliser pour le rendu.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
                layout="absolute"
                creationComplete="creationCompleteHandler()">
 
	<mx:Script>
		<![CDATA[
			import fr.tannoy.renderers.IconRenderer;
			import fr.tannoy.model.Icon;
			import mx.collections.ArrayCollection;
 
			[Bindable]
			private var dp:ArrayCollection = new ArrayCollection();
 
			private function creationCompleteHandler():void
			{
				dp.addItem(new Icon("Cinema Display", 1.20, "128", "assets/CinemaDisplay.png"));
				dp.addItem(new Icon("Monitor", 0.80, "128", "assets/desktop.png"));
				dp.addItem(new Icon("HP Monitor", 1.00, "128", "assets/HP-Monitor-Dock-512.png"));
				dp.addItem(new Icon("Macintosh", 1.40, "128", "assets/mymac.png"));
				dp.addItem(new Icon("LCD TV", 1.30, "128", "assets/nvtv.png"));
			}
		]]>
	</mx:Script>
 
	<mx:HorizontalList x="359" 
		y="22" 
		dataProvider="{dp}" 
		columnWidth="280"
		rowHeight="180"
		height="200"
		itemRenderer="fr.tannoy.renderers.IconRenderer" 
		width="840">
	</mx:HorizontalList>
	<mx:List x="49" 
		y="22" 
		dataProvider="{dp}" 
		rowHeight="180" 
		columnWidth="280"
		itemRenderer="fr.tannoy.renderers.IconRenderer"
		height="540">
	</mx:List>
 
</mx:Application>

Le code complet

En savoir plus