Recycling of renderers is not really designed to handle renderers of mixed types.
One option, if you don¹t have too many rows, is just to make the list tall enough to view every row and scroll it in some container. Another is to have one renderer that chooses different child controls based on some field in the data. HTH, -Alex On 10/2/14, 5:37 PM, "Jason Guild" <[email protected]> wrote: >Hi All: > > >I have a use case where different kinds of items are displayed within a >single control like an <mx:List> or <mx:Tree>. Based on a descriminator >field in each of the data items added to the control, an appropriate >itemRenderer is used to display each kind of item correctly. > >In the mx.controls.listClasses.ListBase class, an 'itemRenderer' >property can be used to set a custom renderer class which is then used >for all items in the control, but there does not seem to be a way to >choose the itemRenderer /conditionally/ based on the data items. Trying >to implement this functionality in a custom ClassFactory is not possible >because it doesn't have any access to the data item. So I ended up >subclassing <mx:Tree> and overriding ListBase.getItemRendererFactory() >like this: > >private const commFac:ClassFactory = new >ClassFactory(ResultTreeItemRenderer); > >override public function getItemRendererFactory(data:Object):IFactory { > var result:IFactory = super.getItemRendererFactory(data); // the >default renderer > var item:ResultItem = data as ResultItem; > > if (item) { > switch (item.type) { > case "community": > case "project": { > result = commFac; > break; > } > } > } > > return result; >} > >ResultItem is my simple VO having a 'type' field. ResultTreeItemRenderer >is my custom renderer based on <s:MXTreeItemRenderer/> which knows how >to render ResultItems that are communities or projects. Items of other >types get rendered by the default renderer class. > >This approach seems like it works, but when I toggle a disclosure node >on the tree, often the wrong itemRenderer is used to draw subordinate >items that become visible. When there is enough content in the >tree/list, scrolling affected items off the visible area awill often >cause the correct renderer to be chosen when that item is redrawn after >more scrolling to make it visible again, per the code above. > >I think the problem is related to how ListBase tries to keep memory >consumption down by caching and reusing itemRenderer instances. The >ListBase.addToFreeItemRenderers() and >ListBase.getReservedOrFreeItemRenderer() methods seem to maintain >multiple lists of itemRenderers available for reuse based on which >IFactory was used to create the renderer. This implies that it is >reasonable to use multiple renderers in the same control. But it's not >clear to me why the wrong type of renderer is sometimes used from the >cache when items become visible (after toggling a disclosure node). It's >also not clear to me why scrolling affected items so as to make them >invisible/visible seems to then cause the right renderer to be used. >Reading List.makeRowsAndColumns() and List.createItemRenderer() aren't >giving me any insights either. > >Am I approaching this the right way? Are there other options for doing >conditional rendering? > >Thanks for any help you can provide, >Jason >
