Looping over itemRenderers in a List

Problem
Looping over the data used by a Flex List component is easy enough, but what if you need to loop over the actual itemRenderers in the List? Recently I needed to do just that.
Solution
The key is understanding the mx_internal namespace
Detailed explanation
Looping over the data used by a Flex List component is easy enough, but what if you need to loop over the actual itemRenderers in the List? Recently I needed to do just that.
I needed a reference to each of the itemRenderers so that I could pass TextInput controls in my custom renderer into a 3rd party spell check library. Anytime you want to do something with the controls inside each of the custom itemRenderers in your list, looping over them will come in handy.
The key to doing it with Flex 3 is understanding the mx_internal namespace. A lot of variables in the Flex framework are mx_internal variables. Variables in the mx_internal namespace are ones that Adobe thinks have a high probability of changing in future versions of Flex, so they reside in a special namespace so developers know they may change. Since the Flex framework is open source, we can easily open the code and find which variables are mx_internal.
The List controls inherits from ListBase. ListBase has a mx_internal variable named rendererArray. rendererArray is just that, an array of renderer’s used by your List. If you try to access rendererArray using the standard List component you wont be able to. To gain access to this array we will need to create a new component that inherits from List. Below is the full source for my ExposedRendererList :

package Controls
{
import mx.controls.List;
import mx.core.mx_internal; //this import statement should appear be last

public class ExposedRendererList extends List
{
use namespace mx_internal; //tells Actionscript that mx_internal is a namespace

public function ExposedRendererList()
{
super();
}

//The array of renderers being used in this list
public function get renderers():Array
{
//prefix the internal property name with its namespace
return mx_internal::rendererArray;
}

}
}
There are 3 lines of code we need to take a look at. The first one is line 4. We need to import mx.core.internal namespace into our new class. On line 8 we tell Actionscript that mx_internal is a namespace we will be using in the class. And finally we create a new property on our class named renderers. The only thing it does is get the rendererArray from ListBase (which is the parent class for List). We have to prefix rendererArray with the mx_internal:: namespace in order to gain access to it. Now we’ve exposed the previously internal array for use anywhere in our Flex application.
Looping over the renderers or components in each of renderers becomes pretty trivial. The one thing to keep in mind is that rendererArray is an Array of Array so we’ll need to write our ActionScript accordingly. Here is a sample method the does a for…each loop over the itemRenderers in a List:
private function LoopOverRenderers():void
{
for each(var renderer:Array in coolstuff.renderers)
{
//renderers is an array of arrays
//in a List component, our renders will be the first element of each array

if(renderer[0] != null)
{
ProductRenderer(renderer[0]).img.rotation += 90;
}
}
}

For more such examples please visit http://www.mithilasoft.com/

Leave a Reply