I am writing an "horizontal list" which is continuous / cyclic ( as in, just after the last item, the first item comes again, and so on ).
At first, I thought using DataGroup and a custom layout would be a good idea.
So I wrote a "ContinuousHorizontalLayout", which does just that.
It's working fine but... items don't get recycled.
This is because in my layout's updateDisplayList, If I am visually near the last item and the group has 10 elements, I would have something like :
target.getVirtualElementAt( 7 );
target.getVirtualElementAt( 8 );
target.getVirtualElementAt( 9 );
target.getVirtualElementAt( 0 );
target.getVirtualElementAt( 1 );
This prevents any recycling because DataGroup assumes a startingIndex lower than the endingIndex. So it sees a 0 and a 9 and will think everything from 0 to 9 is needed.
Question 1 : Should DataGroup record any item index seen in an updateDisplayList pass or do you think the current ( and explained above ) behavior is normal and should not be changed ? If the answer is the latter, do you have an implementation advise for my feature? I could always write everything from scratch using UIComponent but I obviously prefer to reuse the most of the built in SDK classes.
Question 2 : There seem to be a bug for the recycling anyway, as even when I have a more "reasonable" scenario where only indexes 0,1,2 are visible, all the others don't get recycled.
I believe this FOR loop in finishVirtualLayout is flawed :
for (var index:int = oldVirtualLayoutStartIndex; index <= oldVirtualLayoutEndIndex; index++)
// Skip the inView renderers. If vitrualLayoutStartIndex is -1, there aren't any.
if (virtualLayoutStartIndex != -1 && index >= virtualLayoutStartIndex && index <= virtualLayoutEndIndex)
index = virtualLayoutEndIndex;
and index = virtualLayoutEndIndex; should be index = virtualLayoutEndIndex - 1; since the next index++ will just skip the whole recycling process.
I wrote the code you're referring to in question #1 and did not anticipate scenarios where, in general, the indices of the allocated virtual item renderers (IRs) are arbitrary. There are quite a few places in the DataGroup implementation, including the one you've pointed out, that assume it's safe to just visit all the virtual IRs in the range computed at updateDisplayList() time. The implementation could be revised to just track a list of indices instead. That sounds like a worthwhile thing to do. Can you file a bug?
As to question #2, I don't think you're correct. The range includes virtualLayoutEndIndex so the next iteration through the loop begins at the first potentially recyclable IR.
Thank you for your quick answer.
I will fill a bug for #1.
As for #2, I took a look again and you're right.