Flex: image switching place in tilelist

1.7k views Asked by At

I'm running into an odd issue with itemRenderers inside a TileList.

Here is a working example without an itemRenderer: 152.org/flex/

Here is the broken version with an itemRenderer: 152.org/brokenExample/
(I don't have the rep to make both of these a link)

Both examples have "View Source" enabled.

To see the problem use the broken example, select an album and scroll down one row. Scroll back up and the images will be switched. If you try this on the working example it's fine.

This seems to be a widely known bug, but I can't find a solution for it.

UPDATE
I started playing with this example again and found out something else. Turns out you don't have to override the data setter. You can create a new method in the itemRenderer that is set whenever the tile wants to refresh. So the trick is to not rely on the initialize or creationComplete methods.

This is what I have for the itemRenderer in the Application.

<itemRenderers:ImageTile img="{data}"/>

This is the code I have in the itemRenderer.

public function set img(value:String) : void {
  trace("setting source: " + value);
  this.source = value;
  this.name = value.toString().split("/").pop().split(".").shift();
}

I updated my example to reflex this change.

2

There are 2 answers

2
Christian Nunciato On BEST ANSWER

I don't have your app handy, so I can't test end-to-end, but I've looked at your source. You probably need to override the data setter in your itemRenderer:

<?xml version="1.0" encoding="utf-8"?>
<mx:Image xmlns:mx="http://www.adobe.com/2006/mxml" initialize="init()">

 <mx:Script>
  <![CDATA[

   override public function set data(value:Object):void
   {
    super.data = value;
    this.source = data;
    this.name = data.toString().split("/").pop().split(".").shift();
   }

   private function init() : void {
    // Removed from your source and transplanted above
   }

  ]]>
 </mx:Script>

</mx:Image>

Flex will attempt to re-use item renderers in lists (which means the lifecycle events you might be expecting -- initialize, creationComplete, etc. -- won't always fire), so if you want to be sure your renderer gets updated when the data item changes (as it will when scroll events happen), the best practice is to override the renderer's data property. That'll most likely fix the problem.

0
Chris Klepeis On

Maybe try to invalidate on creationComplete?

From what I recall with DataGrids (which work somewhat similarly to a tilelist), when an item comes into focus its recreated.

<mx:itemRenderer>
  <mx:Image id="myImage" creationComplete="myImage.invalidate()" />
</mx:itemRenderer>

Haven't tried this code but I think this is where you want to start looking. I took a look at your itemRenderer component. Try creationComplete instead of initialize to call your function