user355318
user355318

Reputation:

Flex Mobile: List flickers

Ok I have a List with an IconItemRenderer in it. When I set it's dataprovider in AS3 and I begin scrolling, the list is flickering one time (gets white for one frame). This only happens when the messageField/messageFunction is set and there is a different number of lines in the message areas. I'm sure this is a framework bug. Has anyone had the same experience? I would be glad if someone knows a workaround for this. Thanks in advance.


Here's an example code for a view component. Strange to say the flickering seems to take sometimes more, sometimes less time. I tested it on Android and in Desktop mode (adl), error occures on both. The "blabla.." is just to get a string with a random number of lines.

<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
        xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
    <s:actionContent>
        <s:Button label="Set List" click="btn_click(event)"/>
    </s:actionContent>
    <s:List width="100%" height="100%" id="list">
        <s:itemRenderer>
            <fx:Component>
                <s:IconItemRenderer messageField="text"/>
            </fx:Component>
        </s:itemRenderer>
    </s:List>
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayList;

            protected function btn_click(event:MouseEvent):void
            {
                var al:ArrayList = new ArrayList;
                var obj:Object;
                var str:String = "blablablablablablablablablablablablablablablablablablablablabblablablablablablablablablablablablablablablablablablablablabblablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablablabla";
                for(var i:int = 0; i < 20; i++) {
                    obj = new Object;
                    obj.text = str.substr(0, Math.random()*str.length);
                    al.addItem(obj);
                }
                list.dataProvider = al;
            }

        ]]>
    </fx:Script>
</s:View>

See bug report: https://issues.apache.org/jira/browse/FLEX-33383

For the workaround see the correct answer below.

Upvotes: 1

Views: 1056

Answers (3)

user355318
user355318

Reputation:

I eventually found a workaround. Basically it's just faking a drag event when the list dispatches the updateComplete event. This prevents the flickering when the user first starts to scroll and since updateComplete is called before the list is initially shown, there is no flickering at all. The positive side effect is that every time you change to a view with this list in it or when the list gets another data provider, the scroll bar is shown for a moment, so you can guess how large the list is without touching it.

So here's the code. I use this list as a superclass for all of my lists:

import mx.events.FlexEvent;
import mx.events.TouchInteractionEvent;
import spark.components.List;

public class MyList extends List
{
    public function MyList()
    {
        super();

        //add event listeners
        addEventListener(FlexEvent.UPDATE_COMPLETE, updateCompleteHandler);
    }

    //update complete
    protected function updateCompleteHandler(event:FlexEvent):void
    {
        //fake touch start
        fakeTouchEvent(TouchInteractionEvent.TOUCH_INTERACTION_START);
        callLater(endTouch);
    }

    //quit touch event
    protected function endTouch():void {
        //fake touch end
        fakeTouchEvent(TouchInteractionEvent.TOUCH_INTERACTION_END);
    }

    //fake touch event
    protected function fakeTouchEvent(type:String):void {
        var evt:TouchInteractionEvent = new TouchInteractionEvent(type);
        evt.relatedObject = scroller;
        scroller.dispatchEvent(evt);
    }
}

Upvotes: 1

Dimon Buzz
Dimon Buzz

Reputation: 1318

I do too see this issue (Flex 4.6 + AIR 3.1), exactly as described: White flickering occurs only one time, when List is dragged in either direction. It doesn't happen on touch. In my case I don't even use Label/IconItemREnderer, rather I've build a custom ItemRenderer based on this pretty descent walk through here My measure() method doesn't use setElementSize() at all. The issue doesn't happen when virtualLayout=false, which is not acceptable on mobile for large (>200) elements in data provider. Sorry, have no workaround yet.

Upvotes: 0

RIAstar
RIAstar

Reputation: 11912

I think I may have a workaround for you. The problem seems to be related to content justification, so I tried to change the default justification by setting a custom layout with contentJustify instead of the default justify:

<s:VerticalLayout gap="0" 
                  horizontalAlign="contentJustify" 
                  requestedMinRowCount="5" />

This fixed the flicker issue for me, but now the List could also scroll sideways, which was also undesired. This I fixed by setting the horizontalScrollPolicy to off. This is the final result:

<s:List width="100%" height="100%" id="list" horizontalScrollPolicy="off">
    <s:itemRenderer>
        <fx:Component>
            <s:IconItemRenderer messageField="text"/>
        </fx:Component>
    </s:itemRenderer>
    <s:layout>
        <s:VerticalLayout gap="0" horizontalAlign="contentJustify" r
                          equestedMinRowCount="5" />
    </s:layout>
</s:List>

You may want to file this bug officially, though I don't exactly know where you'd have to do that now that Flex is moving from Adobe to Apache.

Upvotes: 1

Related Questions