I created a custom ItemRenderer for a s:list, for it to contain a list of UIComponent which contains a MovieClip. When I scroll some of the items are not shown/rendered, although their parent/x/y properties are correct. here is the code of the list's ItemRenderer. render() occurs when render event is triggered :
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
autoDrawBackground="true" creationComplete="init();" render="render();">
<s:Label id="lbl" text="{data.getName()}" width = "{width}" fontSize="14"/>
<fx:Script>
<![CDATA[
import Types.ReversingMovieClip;
import mx.core.UIComponent;
private var exDisplay:DisplayObject;
private var inited:Boolean = false;
private var uic:UIComponent = new UIComponent();
public function init():void
{
// first item is firing creationComplete twice !
if (!inited)
{
exDisplay = data.getDisplay();
// Dangerous. if exDisplay has a different event of CLICK, it won't set it here.
// On the other hand.. this happens at the startup.. so.. what to do.
if (exDisplay is ReversingMovieClip && !exDisplay.hasEventListener(MouseEvent.CLICK))
exDisplay.addEventListener(MouseEvent.CLICK, playPauseClip);
inited = true;
addElement(uic);
}
}
public function render():void
{
if (exDisplay != null && exDisplay.parent == uic)
uic.removeChild(exDisplay);
exDisplay = data.getDisplay();
//if (exDisplay.width != width && exDisplay.height != width)
resizeDisplay();
uic.width = exDisplay.width;
uic.height = exDisplay.height;
uic.addChild(exDisplay);
//ReversingMovieClip.setPlayBySpeed(true);
//ReversingMovieClip.setSpeed(1);
}
private function resizeDisplay():void
{
if (exDisplay.width > exDisplay.height)
{
exDisplay.width = width;
exDisplay.scaleY = exDisplay.scaleX;
}
else
{
exDisplay.height = width;
exDisplay.scaleX = exDisplay.scaleY;
exDisplay.x = width / 2 - exDisplay.width / 2;
}
uic.y = 12;
/* trace("listw " + width + "\nexHeight " + exDisplay.height + "exWidth " +
exDisplay.width + "\nuicW " + uic.width + " " + uic.height); */
}
private function playPauseClip(e:Event):void
{
var mc:ReversingMovieClip = (e.currentTarget as ReversingMovieClip);
if (mc.isPlaying())
mc.stop();
else mc.play();
}
]]>
</fx:Script>
</s:ItemRenderer>
The positioning of the UIComponent or the data.getDisplay() which returns the MovieClip is not the problem. I use removeChildAt to remove the last MovieClip used by this item, and put the new one. It works, only that some random items not showing while scrolling, and then when you scroll again the do appear.. randomly.
Please help.. Thank you.
You have a lot of code. I'll take a more in depth look, but the gist is that you are not changing your component when the data property of your renderer changes. As such, how will the renderer know when to change the values it displays?
So, first comment is that a single renderer is often created during the List component's initial rendering. This is not unusual to see a creationComplete fire twice.
Second comment is that creationComplete is often a horrible place for any initializing code. Read up on the Flex Component LifeCycle for Spark or Halo. The pre-initialize event is better, or the the initialze event if you want to access a component's children.
Third, you need to research and read about render recycling. The gist is that as you scroll through the list, each renderer is re-used. The data changes. It is not created again. The List component just passes in new data and expects the renderer to know what to do. Your 'creationComplete' code will most likely need to move to a dataChange event handler.
Fourth you should make use of the Flex Component LifeCycle. It looks like your render and resize display methods should move into updateDisplayList() which is supposed to handle sizing and positioning of the components children.
It's going to take quite a bit of time to re-write your renderer; so I gave up half way through. But, read through some of the links I provided, give a crack at it and come back if you have problems.