1

I'm desperately trying to fix a strange behavior in my custom iconitemrenderer list: When I change the view to the view with the list inside and start scrolling, the list gets white for the fraction of a second (apperently completely redrawn), but only once when scrolling the first time after the view change.

In the IconItemRenderer I add a check mark:

<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                    xmlns:s="library://ns.adobe.com/flex/spark">
...
override protected function commitProperties():void
{
    //create checkbox
    if(!checkMarkImage && data.isChecked) {
        //create image holder
        imageHolder = new Group;
        addChild(imageHolder);

        //create image
        checkMarkImage = new BitmapImage();
        checkMarkImage.source = checkBoxSource;

        imageHolder.addElement(checkMarkImage);
    } 
    //delete checkmark
    else if(checkMarkImage && !data.isChecked) {
        removeChild(imageHolder);
        imageHolder = null;
        checkMarkImage = null;
    }

    super.commitProperties();
}

override protected function layoutContents(w:Number, h:Number):void
{
    super.layoutContents(w, h);

    //layout the checkmark
    if(checkMarkImage) {
        // don't do it like this! (see correct answer)
        checkMarkImage.x = w-40;
        checkMarkImage.y = 14;
    }
}

The list change handler sets the mark on the selected item and removes it from the old one. After this is done it calls popView(), but when you come again to this view the list gets created in the views addHandler and when you start scrolling the list behaves as mentioned above.

//list change
protected function myList_changeHandler(event:IndexChangeEvent):void
{
    //is already selected?
    var item:Object = myList.selectedItem;
    if(!item.isChecked) {
        //deselect the other one?
        var length:int = myList.dataProvider.length;
        var oldItem:Object;
        for(var i:int = 0; i < length; i++) {
            oldItem = myList.dataProvider.getItemAt(i);
            if(oldItem.isChecked) {
                oldItem.isChecked = false;
                myList.dataProvider.itemUpdated(oldItem);
                break;
            }
        }

        //select new one
        item.isChecked = true;
        myList.dataProvider.itemUpdated(item);
    }

    //pop view
    navigator.popView();
}

I think the problem is in the myList.dataProvider.itemUpdated(oldItem), apperently the renderer thinks it has to redraw everthing, but I have no idea why.. and why only after the view is shown again...?

Any ideas if it's a bug or something? how can I get rid of this bahavior or how can I debug this this properly? thanks

  • A quick one; but calling itemUpdated on the dataProvider will force the dataChange event to fire in the itemRenderer. I would expect that would force a component to redraw--as that is the only reason to call the itemUpdated function. But I don't see a dataChange event handler in your code, so I'm unclear. – JeffryHouser Feb 29 '12 at 19:09
  • By calling itemUpdated() the itemRenderer can either create a new check mark image or delete the old one, so in fact it has to redraw. In the ItemRenderer I don't use the set data() method but the commitProperties() method since the original optimized imemRenderers do the same. But nonetheless by calling itemUpdated() I want only single list items to redraw, not the whole list. –  Feb 29 '12 at 19:57
  • But the big question is: Why does the list gets redrawed when I start scrolling, thats not necessary –  Feb 29 '12 at 20:01
  • I'm having trouble understanding the code because it seems like you've only provided snippets. If I understand, everything redraws the first time you scroll b/c the initial loop in change handler tells every item to redraw. When does the change handler get fired? From the list or from the renderer? I think you'll need to provide a runnable sample to demo the problem for best results here. – JeffryHouser Feb 29 '12 at 20:28
  • I created a new Application where I just added the required parts. For some reason this behavior is not reproducible. It's the 2nd day now I am trying to figur out a problem that only lasts fraction of a second in the final App -.- –  Feb 29 '12 at 23:23
  • I got it! I don't know why but when I replaced checkMarkImage.x = w-40; checkMarkImage.y = 14; with setElementPosition(checkMarkImage, w-40, 14); in the LayoutContents method of the IconItemRenderer, everythink works fine. –  Feb 29 '12 at 23:38
  • Please post that as a formal answer and select it as the correct one. Without reviewing [and comparing] code behind the x/y properties and the setElementPosition; I'm not sure why one causes issues and the other does't. – JeffryHouser Mar 01 '12 at 14:23

1 Answers1

2

I got it!

I don't know why but when I replace

checkMarkImage.x = w-40;
checkMarkImage.y = 14;

with

setElementPosition(checkMarkImage, w-40, 14);

in the LayoutContents method of the IconItemRenderer, everything works fine.

BenMorel
  • 34,448
  • 50
  • 182
  • 322