by Adobe

adobe_logo_bio

Created

23 March 2010

 Requirements
 
User level
Required products
All Flex (Download trial)
Adobe Flex supports several MX controls that you can use to represent lists of items. These controls let the application user scroll through the item list and select one or more items from the list. All Flex MX list components are derived from the mx.controls.listClasses.ListBase class, and include the following MX controls: DataGrid, HorizontalList, List, Menu, TileList, and Tree.
 
An MX list control gets its data from a data provider, which is a collection of objects. For example, a Tree control reads data from a data provider to define the structure of the tree and any associated data that is assigned to each tree node.
 
The data provider creates a level of abstraction between Flex components and the data that you use to populate them. You can populate multiple components from the same data provider, switch data providers for a component at run time, and modify the data provider so that changes are reflected by all components that use the data provider.
 
You can think of the data provider as the model, and the Flex components as the view of the model. By separating the model from the view, you can change one without changing the other.
 
Each list control has a default mechanism for controlling the display of data, or view, and lets you override that default. To override the default view, you create a custom item renderer.
 
This article discusses the following ways of creating and using item renderers:
 
The Flex Spark components also support item renderers. For information on using item renderers with Spark components, see Using Spark item renderers.
 

 
Using the default MX item renderer

The following example contains an MX DataGrid control that uses the default item renderer to display the information in an XML file. Flex automatically uses the default when you do not specify a custom item renderer.
 
 
Example
<artwork> <piece> <name>The Wall</name> <image>artwork1.jpg</image> <price>250</price> <quantity>5</quantity> </piece> <piece> <name>Blue Flake</name> <image>artwork5.jpg</image> <price>400</price> <quantity>2</quantity> </piece> <piece> <name>Butterfly</name> <image>artwork6.jpg</image> <price>375</price> <quantity>17</quantity> </piece> </artwork>
MXML file
 
<?xml version="1.0" encoding="utf-8"?> <!-- ItemRendererDefault.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="450" height="140"> <fx:Declarations> <fx:Model id="artwork" source="model/artwork.xml"/> </fx:Declarations> <mx:DataGrid rowCount="4" dataProvider="{artwork.piece}"/> </s:Application>

 
Using an MX drop-in item renderer

Several MX controls are designed to work as MX item renderers. This lets you specify these controls as values of the itemRenderer property of an MX list-based control. When you specify one of these controls as a property value, it is called a drop-in item renderer or drop-in item editor.
 
To use an MX component as a drop-in item renderer or drop-in item editor, a component must implement the IDropInListItemRenderer interface. The following MX controls implement the IDropInListItemRenderer interface, making them usable directly as a drop-in item renderer or drop-in item editor: Button, CheckBox, DateField, Image, Label, NumericStepper, Text, TextArea, and TextInput.
 
You can define your own components for use as drop-in item renderers or drop-in item editors. The only requirement is that they, too, implement the IDropInListItemRenderer interface.
 
In this example, you use the MX Image control as a drop-in item renderer to display thumbnail representations of various artwork and the MX NumericStepper control as a drop-in item renderer to give the user an easy way of altering the quantity field.
 
 
Example
<artwork> <piece> <name>The Wall</name> <image>assets/artwork1.jpg</image> <price>250</price> <quantity>5</quantity> </piece> <piece> <name>Blue Flake</name> <image>assets/artwork5.jpg</image> <price>400</price> <quantity>2</quantity> </piece> <piece> <name>Butterfly</name> <image>assets/artwork6.jpg</image> <price>375</price> <quantity>17</quantity> </piece> </artwork>
MXML file
 
<?xml version="1.0" encoding="utf-8"?> <!-- ItemRendererDropIn.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="470" height="340"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <fx:Model id="artwork" source="model/artwork.xml"/> </fx:Declarations> <mx:DataGrid rowCount="10" variableRowHeight="true" dataProvider="{artwork.piece}"> <mx:columns> <!-- Drop-in item renderer: Image control --> <mx:DataGridColumn dataField="image" headerText="Image" itemRenderer="mx.controls.Image"/> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Price" dataField="price"/> <!-- Drop-in item renderer: NumericStepper control --> <mx:DataGridColumn headerText="Quantity" dataField="quantity" itemRenderer="mx.controls.NumericStepper"/> </mx:columns> </mx:DataGrid> <mx:LinkButton textAlign="center" label="Photos (c) 2006 geishaboy500 (CC Attribution License)" click="{navigateToURL(new URLRequest('http://www.flickr.com/photos/geishaboy500/'));}" /> <fx:Script> <![CDATA[ import flash.net.navigateToURL; ]]> </fx:Script> </s:Application>

 
Creating an MX inline item renderer

Drop-in item renderers are very easy to use but their major drawback is that you cannot configure them. To create more flexible item renderers, you can develop your item renderer as an inline component.
 
Note: The data model for this example differs from the one in the drop-in item renderer example. In that example, each image field contains the relative path to the folder that the images are stored in. The reason this information is in the data model is because you cannot configure the drop-in item renderer to manipulate its source property before setting it. The data model for this example is much cleaner because using an inline item renderer does allow this.
 
 
Example
<artwork> <piece> <name>The Wall</name> <image>artwork1.jpg</image> <price>250</price> <quantity>5</quantity> </piece> <piece> <name>Blue Flake</name> <image>artwork5.jpg</image> <price>400</price> <quantity>2</quantity> </piece> <piece> <name>Butterfly</name> <image>artwork6.jpg</image> <price>375</price> <quantity>17</quantity> </piece> </artwork>
MXML file
 
<?xml version="1.0" encoding="utf-8"?> <!-- ItemRendererInline.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="525" height="525"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <fx:Model id="artwork" source="model/artwork.xml"/> </fx:Declarations> <mx:DataGrid rowCount="3" variableRowHeight="true" dataProvider="{artwork.piece}"> <mx:columns> <!-- Drop-in item renderer: Image control --> <mx:DataGridColumn dataField="image" headerText="Image" width="150"> <mx:itemRenderer> <fx:Component> <mx:VBox width="100%" height="140"> <mx:Image source="{data.image}"/> <mx:Label text="{data.image}" /> </mx:VBox> </fx:Component> </mx:itemRenderer> </mx:DataGridColumn> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Price" dataField="price"/> <mx:DataGridColumn headerText="Quantity" dataField="quantity"> <!-- Inline item renderer --> <mx:itemRenderer> <fx:Component> <mx:VBox horizontalAlign="center" verticalAlign="middle"> <mx:NumericStepper maximum="{data.quantity}"/> </mx:VBox> </fx:Component> </mx:itemRenderer> </mx:DataGridColumn> </mx:columns> </mx:DataGrid> <mx:LinkButton textAlign="center" label="Photos (c) 2006 geishaboy500 (CC Attribution License)" click="{navigateToURL(new URLRequest('http://www.flickr.com/photos/geishaboy500/'));}" /> <fx:Script> <![CDATA[ import flash.net.navigateToURL; ]]> </fx:Script> </s:Application>

 
Creating a reusable MX inline item renderer

Rather than defining an inline item renderer in the definition of a component, you can define a reusable inline item renderer for use in multiple locations in your application. You create reusable inline item renderers by using the <fx:Component> tag, setting your inline component's id property, and binding the itemRenderer property of your control to your inline component's id property.
 
Even if you do use an item renderer more than once, using reusable inline item renderers results in code that is easier to maintain because you can group all your item renderers in a single place in your MXML document.
 
In this example, you create two reusable MX item renderers. The first one displays an image of the current art piece and a label with the image's file name in a VBox container. The second item renderer displays a Numeric Stepper component and sets its maximum property to use the quantity value of a specific art piece so that the user cannot choose to purchase more items than there are in stock.
 
 
Example
<artwork> <piece> <name>The Wall</name> <image>artwork1.jpg</image> <price>250</price> <quantity>5</quantity> </piece> <piece> <name>Blue Flake</name> <image>artwork5.jpg</image> <price>400</price> <quantity>2</quantity> </piece> <piece> <name>Butterfly</name> <image>artwork6.jpg</image> <price>375</price> <quantity>17</quantity> </piece> </artwork>
MXML file
 
<?xml version="1.0" encoding="utf-8"?> <!-- ItemRendererReusable.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="525" height="525"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <fx:Model id="artwork" source="model/artwork.xml"/> <!-- Reusable inline item renderers --> <fx:Component id="ImageRenderer"> <mx:VBox width="100%" height="140"> <mx:Image source="{data.image}"/> <s:Label text="{data.image}"/> </mx:VBox> </fx:Component> <fx:Component id="NumericStepRenderer"> <mx:VBox horizontalAlign="center" verticalAlign="middle"> <mx:NumericStepper maximum="{data.quantity}"/> </mx:VBox> </fx:Component> </fx:Declarations> <mx:DataGrid rowCount="3" variableRowHeight="true" dataProvider="{artwork.piece}"> <mx:columns> <mx:DataGridColumn dataField="image" headerText="Image" width="150" itemRenderer="{ImageRenderer}" /> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Price" dataField="price"/> <mx:DataGridColumn headerText="Quantity" dataField="quantity" itemRenderer="{NumericStepRenderer}" > </mx:DataGridColumn> </mx:columns> </mx:DataGrid> <mx:LinkButton textAlign="center" label="Photos (c) 2006 geishaboy500 (CC Attribution License)" click="{navigateToURL(new URLRequest('http://www.flickr.com/photos/geishaboy500/'));}" /> <fx:Script> <![CDATA[ import flash.net.navigateToURL; ]]> </fx:Script> </s:Application>

 
Using an MX component as an item renderer

It is easier to create maintainable and scalable applications if you break them into multiple smaller, well-encapsulated pieces. In Flex, you can follow such a modular workflow by using custom components.
 
One way of defining custom components in Flex is by using MXML. A custom component has its own MXML document in which the root tag may be any Flex component other than the Application container.
 
In the following example, you extract the two reusable inline item renderers into their own MXML documents, making them custom components. To use a custom component as an item renderer, specify its name as the value for another control's itemRenderer property.
 
Note: With reusable inline item renderers you use data binding to bind to the item renderer. When you use a component as an item renderer, you do not use data binding but specify the name of the custom component to use as an item renderer.
 
 
Example
ImageRenderer.mxml component
 
<?xml version="1.0" encoding="utf-8"?> <!-- ImageRenderer.mxml --> <mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="140"> <mx:Image source="{data.image}"/> <s:Label text="{data.image}"/> </mx:VBox>
NumericStepRenderer.mxml component
 
<?xml version="1.0" encoding="utf-8"?> <!-- NumericStepRenderer.mxml --> <mx:VBox xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"> <mx:NumericStepper maximum="{data.quantity}"/> </mx:VBox>
Main application file
 
<?xml version="1.0" encoding="utf-8"?> <!-- ItemRendererComponent.mxml --> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="525" height="525"> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <fx:Model id="artwork" source="model/artwork.xml"/> </fx:Declarations> <mx:DataGrid rowCount="3" variableRowHeight="true" dataProvider="{artwork.piece}"> <mx:columns> <!-- Use the ImageRenderer custom component as an item renderer --> <mx:DataGridColumn dataField="image" headerText="Image" width="150" itemRenderer="ImageRenderer"/> <mx:DataGridColumn headerText="Name" dataField="name"/> <mx:DataGridColumn headerText="Price" dataField="price"/> <!-- Use the NumericStepRenderer custom component as an item renderer. --> <mx:DataGridColumn headerText="Quantity" dataField="quantity" itemRenderer="NumericStepRenderer"> </mx:DataGridColumn> </mx:columns> </mx:DataGrid> <mx:LinkButton textAlign="center" label="Photos (c) 2006 geishaboy500 (CC Attribution License)" click="{navigateToURL(new URLRequest('http://www.flickr.com/photos/geishaboy500/'));}"/> <fx:Script> <![CDATA[ import flash.net.navigateToURL; ]]> </fx:Script> </s:Application>

 
For more information