• 24apr

    When using wx:TileList with your own ItemRenderer, you have to remember two important things to avoid scrolling problems:

    1. If you override the set data method, remember to call super.data = value.
    2. Remember that the TileList reuses the ItemRenderer instances when scrolling the component! So, if you have a TileList with 5 rows and 5 cols, and an array with 500 elements as DataProvider, it will create about 25 instances of your ItemRenderer, calling the set data method on them when scrolling. So, if you add some child to your ItemRenderer under some data condition (like I did), remember to remove them if the data condition is not valid.

    Posted by Armisael @ 06:29

    Tags: ,

6 Responses

WP_Cloudy
  • Matthew Wilson Says:

    I’m having an issue with my TileList control…and it kinda’ sounds like what you describe. When I scroll vertically in my TileList, I get these “ghost” images that jump from one tile to the next. So an image that should be in tile 3, appears in tile 1 IN ADDITION to the images that are supposed to be in tile 1.

    So it’s like the itemRenderer is getting called several times for each tile, or something. Anyway, if you could elaborate on your statement above. I would love to get some more information to see if it can help me with my issue.

    Great blog! Thanks for posting!

  • Armisael Says:

    Ok, I think I could elaborate on that =)
    Take this method:

    override public function set data(d:Object):void
    {
      super.data = d;
      if (data != null) {
        if (data.image != null) createAndAddImage();
        // other stuff
      }
    }

    This functions has a problem. Suppose that the first data has an image: when the TileList call the set method, the image will be added to the tile. Now, we scroll down the component. The TileList probably will reuse the tile instance, for example for the 25th data. If data[25] does not have an image, nothing happens, but the first image is still on the tile and it will appear as “ghost” image. So, we have to call a method to remove all the images on the tile if the data object does not contain an image:

      if (_data != null) {
        if (_data.image != null) createAndAddImage();
        else removeAllImages();
        // other stuff
      }

    Hope it could help you!

  • Bhootnath Says:

    hi, am also having this ghost image problem.. problem is that i even commented the custom renderer.. and still the ghost images remain.. The datasource has 7 items and i had set the tile list to 3X2 and when I scroll down, the last row where there should have been only one image, in the first box, the last two show faded images 5 and 6.. :-S.. any insight?

  • Armisael Says:

    I’m sorry but I cannot understand. If you have commented out your custom renderer, how do you tell to the TileList to show an image? Are you saying that even if the TileList has no Renderer, it uses the last you have defined? Can you post some kind of source code?

  • Bhootnath Says:

    it is using its default renderer..

    var _dp:DataProvider = new DataProvider();
    var _pageNumber:Number = 0;
    for (_pageNumber = 0; _pageNumber < tnArray.length; _pageNumber++ )
    {
    var _currLabel:String = "Page " + String(_pageNumber + 1);
    var tnPath:String = serverPath + fileServerURL + "?fpath=" + tnArray[_pageNumber];
    _dp.addItem( { label:_currLabel, source:tnPath, commentCount: String(_commentCountSet.getItemAt(_pageNumber)) } );
    }
     
    thumbnailTileList = new TileList();						
    thumbnailTileList.width = 340;// this.width - 20;
    thumbnailTileList.height = 230;// this.height - 80;230=330
    thumbnailTileList.scrollPolicy = ScrollPolicy.ON;
    thumbnailTileList.direction = ScrollBarDirection.VERTICAL;			
    thumbnailTileList.x = 10;
    thumbnailTileList.y = 40;			
    //thumbnailTileList.setStyle("cellRenderer", ThumbnailRenderer);
    thumbnailTileList.addEventListener(ListEvent.ITEM_CLICK, thumbnailSelectedClickHandler);
     
    thumbnailTileList.columnWidth = 102;
    thumbnailTileList.rowHeight = 102;
    //thumbnailTileList.columnCount = 3;
    thumbnailTileList.rowCount = 2;
    thumbnailTileList.x = 10;
    thumbnailTileList.y = 35;
    thumbnailTileList.dataProvider = _dp;

    The 3rd parameter in the data provider is the one for which I had to write the custom renderer but when I started getting the ghost image problem, i commented the line where I was setting the custom cell renderer. In this example, I had 7 images to display while the visible part of Tile list was set to 3X2. When I scrolled down to the last row, all three columns had images in them, first one had real image and last two the ghost of previous row. Can you give some example on what should be done in the removing image routine.. I have tried everything, i can even get any event when i scroll down to the last row, i have tried on render, label change, and lot more but none of the events are called when i scroll down to the last row.. strangely they do get called when I scroll back up.. :S..

  • Armisael Says:

    It’s very strange, you’re right…
    The code seems to be ok… I thought that the “ghost” problem was appearing only for custom renderers, but it seems that it’s not true. Maybe it’s really a bug of Flex.

    I think that what it’s happening is that the TileList creates only 6 tiles, calling the set data method on them using your dataProvider. When you scroll down, it calls it only for the 7th tile. Probably, because there are no other data in the dataProvider, it does not call any method on the other two tiles, leaving them as they are, with the previous image (and this is the problem). Using a custom renderer we can manage this problem, but with the default one it seems we cannot.

    The fastest (and not so clean) solution I would try, is to add some dummy data with empty source at the end of the dataProvider, reaching a multiple of the tileList colCount. I don’t know exactly what can be happen, but it could be that founding some data, the tileList will call the set method also on the other tiles, cleaning the image because of the empty source.

Leave a Comment