itemRenderers: Part 1: inline renderers


I’m starting a new series of articles on itemRenderers. Our documentation team has great examples so please check that information out first. I’m giving you my distillation of it.

Recycling Renderers

One thing many people try to do is access an itemRenderer from outside of the list. For example, you might want to make the cell in the 4th column of the 5th row in a DataGrid turn green because you’ve just received new data from the server. Getting that itemRenderer instance and modifying it externally would be a huge breech of the Flex framework and component model.

To understand itemRenderers you have to understand why they are what they are and what our intentions were when we designed them. BTW – when I say ‘we’ I really mean the Adobe Flex engineering team – I had nothing to do with it. Anyway, suppose you have 1000 records you want to show. If you think the list control creates 1000 itemRenderers you are incorrect. If the list is showing only 10 rows, the list creates about 12 itemRenderers – enough to show every visible row plus a couple for buffering and performance reasons. The list initially shows rows 1 through 10. When the user scrolls the list it may now be showing rows 3 – 12. But those same 12 itemRenderers are still there – no new itemRenderers were created, even after the list scrolled.

Here’s what we do. When the list is scrolled, those itemRenderers which will still be showing the same data (rows 3 – 10) are moved upward. Aside from being in a new location, they haven’t changed. The itemRenderers that were showing the data for rows 1 and 2 are now moved below the itemRenderer for row 10. Then those itemRenderers are given the data for rows 11 and 12. In other words, unless you resize the list, those same itemRenderers are reused – recycled – to a new location and are now showing new data.

If you want to change the background color of the cell in the 4th column of the 5th row, be aware that the itemRenderer for that cell may now be showing the contents of the 21st row if the user has scrolled the list.

So how do you make changes like this?

The itemRenderers must change themselves based on the data they are given to show. If the itemRenderer for the list is supposed to change its color based on a value of the data, then it must look at the data it is given and change itself.

inline itemRenderers

In this article we’ll look at the answer to this problem using inline itemRenderers. An inline itemRenderer is one which is written directly in the MXML file where the list control occurs. In the next article we’ll look at writing external itemRenderers. The inline itemRenderers are the least complex and are generally used for very simple renderers or for prototyping a larger application. There’s nothing wrong with inline itemRenderers, but when the code becomes complex it is better to extract it into its own class.

In all of the examples we’ll use the same data: a collection of information about books: author, title, publication date, thumbnail image, and so forth. Each record is an XML node which looks like this:

<author>Peter F. Hamilton</author>
<title>Pandora's Star</title>
<date>Dec 3, 2004</date>

Let’s start with a simple itemRenderer using a <mx:List> control. Here, the author is listed followed by the title of the book.

	<mx:List x="29" y="67" dataProvider="{}" width="286" height="190">
<mx:Label text="{}: {data.title}" />

This itemRenderer is so simple that a labelFunction would probably have been better, but it at least lets you focus on the important parts. First, an inline itemRenderer uses the <mx:itemRenderer> tag to define it. Within this tag is the <mx:Component> tag. This tag must be here as it tells the Flex complier you are defining a component inline. We’ll discuss what this really means in a bit.

Within the <mx:Component> tag you define your itemRenderer. For this example it is a single <mx:Label> with its text field set to a data-binding expression: {}: {data.title}. This is very important. The list control gives each itemRenderer instance the record of the dataProvider by setting the itemRenderer’s data property. Looking at the code above, it means that for any given row of the list, the itemRenderer instance of its inline itemRenderer will have its data property set to a <book> XML node (such as the one above). As you scroll through the list, the data property is being changed as the itemRenderers are recycled for new rows.

In other words, the itemRenderer instance for row 1 might have its set to "Peter F. Hamilton" now, but when it scrolls out of view, the itemRenderer will be recycled and the data property – for that same itemRenderer – may now have its set to "J.K. Rowling". All of this happens automatically as the list scrolls – you don’t worry about it.

Here’s a more complex inline itemRenderer using the <mx:List> control again:

	<mx:List x="372" y="67" width="351" height="190" variableRowHeight="true" dataProvider="{}">
<mx:HBox >
<mx:Image source="{data.image}" width="50" height="50" scaleContent="true" />
<mx:Label text="{}" width="125" />
<mx:Text  text="{data.title}" width="100%" />

This really isn’t much different. Instead of a <mx:Label> the itemRenderer is an <mx:HBox> with an <mx:Image>, <mx:Label>, and a <mx:Text> control. Data-binding still relates the visual with the record.


You can use inline itemRenderers on a DataGrid, too. Here’s one applied to a column:

	<mx:DataGrid x="29" y="303" width="694" height="190" dataProvider="{}" variableRowHeight="true">
<mx:DataGridColumn headerText="Pub Date" dataField="date" width="85" />
<mx:DataGridColumn headerText="Author" dataField="author" width="125"/>
<mx:DataGridColumn headerText="Title" dataField="title">
<mx:HBox paddingLeft="2">
override public function set data( value:Object ) : void { = value;
var today:Number = (new Date()).time;
var pubDate:Number = Date.parse(;
if( pubDate > today ) setStyle("backgroundColor",0xff99ff);
else setStyle("backgroundColor",0xffffff);
<mx:Image source="{data.image}" width="50" height="50" scaleContent="true" />
<mx:Text width="100%" text="{data.title}" />

As you can see, this is much more complex than the last two, but it has the same structure: <mx:itemRenderer> with <mx:Component> definition inside of it.

The purpose of <mx:Component> is to provide an MXML syntax for creating an ActionScript class right in the code. Picture the code that appears in the <mx:Component> block being cut out and put into a separate file and given a class name. When you look at the inline itemRenderer it does look like a complete MXML file, doesn’t it? There’s the root tag (<mx:HBox> in this case) and even a <mx:Script> block.

The purpose of the <mx:Script> block in this example is to override the set data function so the background color of the itemRenderer can be changed. In this case, the background is changed from white whenever the publication data for a book is in the future. Remember that itemRenderers are recycled, so the color must also be set back to white if the test fails. Otherwise all of the itemRenderers will eventually turn purple as the user scrolls through the list.


The scope has also changed. What I mean is, variables that you define from within a <mx:Component> are only scoped to that component/inline itemRenderer. Likewise, the content outside of the <mx:Component> is in a different scope, just as if this component were defined in a separate file. For instance, suppose you add a Button to this itemRenderer that allows the user to by the book from an online retailer. Buttons call functions on their click event, so you might define the button like this:

<mx:Button label="Buy" click="buyBook(data)" />

If the buyBook() function were defined in the <mx:Script> block of the file you would get an error saying that buyBook() is an undefined method. That’s because buyBook() is defined in the scope of the file, not in the scope of the <mx:Component>. Since this is a typical use case there is a way around that using the outerDocument identifier:

<mx:Button label="Buy" click="outerDocument.buyBook(data)" />

The outerDocument identifier changes the scope to look into the file, or outer document, with reference to the <mx:Component>. Now beware: the function has to be a public function, not a protected or private one. Remember that <mx:Component> is treated as an externally defined class.

Bubbling Events

Let’s look at another, even more complex example. This is a TileList using the same data.

	<mx:TileList x="29" y="542" width="694" dataProvider="{}" height="232" columnWidth="275" rowHeight="135" >
<mx:HBox verticalAlign="top">
<mx:Image source="{data.image}" />
<mx:VBox height="115" verticalAlign="top" verticalGap="0">
<mx:Text text="{data.title}" fontWeight="bold" width="100%"/>
<mx:Spacer height="20" />
<mx:Label text="{}" />
<mx:Label text="Available {}" />
<mx:Spacer height="100%" />
<mx:HBox width="100%" horizontalAlign="right">
<mx:Button label="Buy" fillColors="[0x99ff99,0x99ff99]">
var e:BuyBookEvent = new BuyBookEvent();
e.bookData = data;

The itemRenderer looks like this when the application is run:

This itemRenderer is pretty close to the one used in the DataGrid, but the Buy button’s click event doesn’t use outerDocument to call a function. In this case the click event creates a custom event which bubbles up out of the itemRenderer, through the TileList, and is received by some higher component in the visual chain.

This is a very common problem: you have an itemRenderer which has some interactive control in it, usually a Button, LinkButton, etc. that is supposed to cause some action to take place when clicked. Perhaps it is to delete the row or in this case, buy the book.

It is unreasonable to expect the itemRenderer to do the work. Afterall, the itemRenderer’s job is to make the list look good – period. Event bubbling allows the itemRenderer to pass off the work to something else. A custom event is useful here because the event is related to the data on the row – so why not include that data in the event; the receiver of the event won’t have to go hunt it down.


Using inline itemRenderers is a great and quick way to give your lists a custom look. Consider inline itemRenderers as separate ActionScript classes – afterall, they are scoped as if they were. If you must refer to functions or properties in the containing file, use the outerDocument identifier to change the scope. If you need to communicate information as the result of an interaction with the itemRenderer, use a custom, bubbling, event.

And remember: don’t try to get hold of itemRenderers – they are recycled for a purpose. Make them responsible only to the data given to them.

In the next article I’ll discuss external itemRenderers.

26 Responses to itemRenderers: Part 1: inline renderers

  1. Paul Boster says:

    What about an item renderer that you want to reuse on another column in the same DataGrid. For example, I want the text to look like an HTML link in more than one column.

    I managed to make this work based on another article but what’s the correct way to do that?
    Peter: The proper way to do this is by using an external itemRenderer which is the subject of the next article.

  2. Jacques Joubert says:

    Hi Peter,

    Great article, it really breaks it down for me to understand. I had a couple of issues regarding the re-use of renderers, plainly because I did not completely understand how flex re-uses them internally. Thanks for clarifying! Looking forward to the next article.

  3. Ken says:

    Peter, thanks for the great article. I’m new to Flex but I’ve been reading blogs and articles everyday to learn more. I have a question though : I have a custom renderer for a specific data item that is sometimes blank. When its not blank, I’d like a button to appear. Is this too much work for the renderer? I’m having trouble making the button disappear rather than show up.

    Could you please provide some tips/advice ?

    Thank you very much. I look forward to reading more articles on your blog.
    Peter: This is a good case for using states. I should add an article about, that, too. Since you are new to Flex, using states right away would be confusing, so I’ll skip that for now. When you make your itemRenderer, add and declare the var showButton:Boolean = false; inside of the itemRenderer.

    Then, in the set data override, determine if the button should or should not visible and set showButton accordingly. Remember that you can use data binding for almost any property or style, not just text and label.

  4. river says:

    Hi Peter,
    thanks for the great article,I want to translate this article, although my English is poor,I will make great efforts to do it。
    If you have any questions please contact me ,my email is

  5. Jana says:


    I tried creating an item renderer two different ways. One is with MXML and the other is with Action Script extending UIComponent. I ran both thru the profiler and I don’t see a difference in the amount of memory used. I thought the advantage of not using a container was in the amount of memory used and to reduce sluggishness when scrolling the datagrid horizontally (it is sluggish). Below are the two pieces of code. For the sake of simplicity I left out the code that actually modifies the value of the txt variable.

    I can’t get the mxml to display in this text area so I’ll describe it. I have a hbox containing a label, and button in it.

    public class RendererCRFRun extends UIComponent implements IListItemRenderer
    private var txt:String;

    private var editrunbutton:Button = new Button();
    private var lbl:Label = new Label();

    private var stylestr:String = “”;

    // Make the data property bindable.

    public function RendererCRFRun()

    // Internal variable for the property value.
    private var _data:Object;

    // Define the getter method.
    public function get data():Object {
    return _data;

    // Define the setter method, and dispatch an event when the property
    // changes to support data binding.
    public function set data(value:Object):void {
    _data = value;

    dispatchEvent(new FlexEvent(FlexEvent.DATA_CHANGE));

    //create your children here
    override protected function createChildren():void{

    lbl.x = 10;
    lbl.y = 2;
    lbl.width = 220;
    lbl.height = 40;
    lbl.text= txt;
    editrunbutton.x = 240;
    editrunbutton.y = 2;
    editrunbutton.height = 20;

    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    //txt.styleName = getStyle(‘myawesometextstyleName’);

    lbl.text = txt;

  6. min says:

    Great article, but if you could include the exercise code/files, that would be amesome.
    Peter: I’ll include the source in the last article.

  7. JP Venter says:


    Couldn’t get the outerDocument property to compile without “Access of undefined property outerDocument”. Had to use parentDocument. Any special reason for this Peter or are they one in the same. Using flex 3.

    Thanks, JP
    Peter: They are not the same thing. The outerDocument is the MXML file your inline itemRenderer lives within. Are you sure you enclosed your itemRenderer within ? Are you using an inline itemRenderer?

  8. kassel says:

    Very good and detailed i’ll study by the time, thank a lot.

  9. judah says:

    In the last example, Bubbling Events, you are dispatching an event. Where do you setup the listener for that? Can you post the BuyBookEvent code? Thanks again!

  10. 小小菜鸟 says:

    thinks very much for your tutorial,
    can u publish the source code?

  11. pascal says:

    Hi Peter,

    Thanks for the great article.

    I have a requirement where in i have to show/hide an icon which is placed in the itemRenderer of the DatagridColumn only on mouse over. i.e. when i move the mouse on any item i need to check the db value and show/hide the button which is in the ItemRenderer.

    On ItemRollOver How can i access the control which is placed in the Itemrenderer?

    Thanks in advance

  12. Peter Ent says:

    Think about this, when you move the mouse over anything, how fast do you want a reaction? Pretty quickly, I’d imagine. If the mouse-over is going to trigger a call to a server somewhere to determine what to do, that reaction will be fairly slow. The user would lose patience.

    If at all possible, include that extra information in your call which populates the data. Then the mouse over – which should be an event in the itemRenderer – can examine the data object and use it to change the visibility of the icon or button.

  13. Brian G says:

    Thank you!!! I had been looking for the outerDocument expression for days. Thanks for the great article.

  14. Taras Khoma says:

    I need to write some simple custom component: List of checkboxes with XML dataprovider. The task is very simple but I have one conflict. When I select some checkbox items in the list, scroll round the list my choice hides and checked items jumping round the list.
    This article helped me to understand the reasons of my trouble but I can’t find any resolve or any way to move for finding resolve of my problem.
    How can I save component’s view with data.

    But there is one more thing. If my provider is ArrayCollection with simple structure all work finelly

  15. tooch says:

    I’m using an HTTPService to populate a datagrid of books with title and isbns (and some other fields). I have a custom itemrenderer for one column that has to use another HTTPService to determine its content (a link to the book or another link).Basically that column needs the value of the isbn column to determine what to display. The service needs to be called as part of the rendering of the grid. Is there an event to use for this, like a load event on a datagrid column.

  16. Taras, it seems you need to call list.dataProvider.refresh(); method each time you want to update the data.

  17. SesliSohbet says:

    thank you
    can u publish the source code?
    Check the next article in the series; you can also find more information on the Flex DevNet site.

  18. sesli chat says:

    Check the next article in the series; you can also find more information on the Flex DevNet site.

  19. Check the next article in the series; you can also find more information on the Flex DevNet site.

  20. Plamen Andreev says:

    Nice tutorial.
    But I’ve a problem. When I use

    The picture shows the border and brokenImage icon.
    If I hard code the image with @Embed, the image appears … Do you know where can be the problem?

  21. regis says:

    Some people can teach and make the learner feel good. Some can’t. You definitely are part of the earlier group. Thanks for making this seem so easy!

  22. Peter Ent says:

    The @Embed syntax is compiling the image into the SWF and replacing the @Embed with a reference to the compiled image.

    Using {data.image} tells the compiler that data.image is a reference available at runtime. For example, data.image should resolve to something like this:

    public var image:Class;

  23. Check the next article in the series; you can also find more information on the Flex DevNet site.

  24. Plamen Andreev says:

    Thanks Peter,
    I’ve found my error. When I use Embed tag the compiler looks inside my src folder and embeds the picture. If I use it without embeding, then the picture should be placed inside the bin directory and loaded at runtime. Hope that helps somebody :).

  25. Hi!
    Nice tutorial.
    But I’ve a problem. When I