Flex移动应用中的Spark List:下拉刷新 - 带有测试代码和屏幕截图

时间:2013-02-22 10:48:05

标签: flex flex4 flex4.5 flex4.6 flex-mobile

尝试实现“下拉​​刷新”我创建了以下简单的测试代码(请添加到新的Flash Builder项目,使用“空白”模板,即不使用导航栏):

截图:

enter image description here

TestPull.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    applicationComplete="init()">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.events.PropertyChangeEvent;

            private static const PADDING:uint = 20;

            [Bindable]
            private var _ac:ArrayCollection = new ArrayCollection();

            private function init():void {
                updateList();
                _list.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handleScroll);
            }

            private function updateList():void {
                _ac.source = new Array();
                for (var i:int = 0; i < 42; i++) {
                    _ac.source.push(Math.random());
                }
                _ac.refresh();
            }

            private function handleScroll(e:PropertyChangeEvent):void {
                if (e.source == e.target && e.property == "verticalScrollPosition") {
                    trace(e.property, ': ', e.oldValue, ' -> ', e.newValue);
                    if (e.newValue < -2 * PADDING && 
                        e.oldValue >= -2 * PADDING) {
                        _hint.visible = true;
                        setTimeout(hideHint, 2000);
                        //updateList();
                    }
                }
            }

            private function hideHint():void {
                _hint.visible = false;
            }
        ]]>
    </fx:Script>

    <s:List id="_list"
            dataProvider="{_ac}"
            width="100%" 
            height="100%" />

    <s:Label id="_hint"
             text="Pull down to refresh..."
             width="100%"
             textAlign="center"
             fontStyle="italic"
             backgroundColor="#FFFFCC"
             paddingTop="{PADDING}"
             paddingBottom="{PADDING}"
             visible="false" />
</s:Application>

这似乎运作良好,_hint可见性每次拉动只需切换一次(我已通过跟踪验证了这一点)。

然而,当我取消注释上面的updateList()调用(模拟从Web服务器获取数据)时 - 一切都中断,hint.visible=true一次又一次地设置,_list闪烁。

请有人建议,如何解决我的穷人拉动刷新的问题?

1 个答案:

答案 0 :(得分:1)

我最终得到了基于Michaël CHAIZE blog条目的解决方案:

enter image description here

TestPull.mxml (添加到新的Flex Mobile项目):

<?xml version="1.0" encoding="utf-8"?>
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    applicationComplete="init()">

    <fx:Declarations>
        <s:ArrayCollection id="_ac"/>
        <s:Fade id="_fadeIn" duration="500" alphaFrom="0" alphaTo="1" />
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            import mx.events.PropertyChangeEvent;

            private static const PADDING:uint = 20;

            private function init():void {
                updateList();
                _list.dataGroup.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, handleScroll);
            }

            private function handleScroll(event:PropertyChangeEvent):void {
                if (_busy.visible || 
                    event.source != event.target || 
                    event.property != 'verticalScrollPosition') {
                    return;
                }

                if (event.newValue < -3 * PADDING && 
                    event.oldValue >= -3 * PADDING) {
                    _hintDown.visible = true;
                    _hintUp.visible = false;
                    _fadeIn.play([_hintDown]);
                } else if (event.newValue < -6 * PADDING && 
                           event.oldValue >= -6 * PADDING) {
                    _hintDown.visible = false;
                    _hintUp.visible = true;
                    _fadeIn.play([_hintUp]);
                } else if (event.newValue >= -6 * PADDING && 
                           event.oldValue < -6 * PADDING) {
                    _hintDown.visible = true;
                    _hintUp.visible = false;
                    _fadeIn.play([_hintDown]);
                } else if (event.newValue >= -3 * PADDING && 
                           event.oldValue < -3 * PADDING) {
                    _hintDown.visible = false;
                    _hintUp.visible = false;
                }
            }

            private function startLoading(event:MouseEvent):void {
                if (_hintUp.visible) {
                    _busy.includeInLayout = _busy.visible = true;
                    setTimeout(updateList, 5000);
                }
                _hintDown.visible = false;
                _hintUp.visible = false;
            }

            private function updateList():void {
                _ac.source = new Array();
                for (var i:int = 0; i < 42; i++) {
                    _ac.source.push(Math.random());
                }
                _ac.refresh();
                _busy.includeInLayout = _busy.visible = false;
            }

        ]]>
    </fx:Script>

    <s:VGroup width="100%">
        <s:HGroup id="_busy"
                  verticalAlign="baseline"
                  includeInLayout="false" 
                  visible="false">
            <s:BusyIndicator />
            <s:Label text="Loading data..." />
        </s:HGroup>

        <s:List id="_list"
                width="100%"
                contentBackgroundColor="#FFFFFF"
                dataProvider="{_ac}"
                mouseUp="startLoading(event)" />
    </s:VGroup>

    <s:Label id="_hintDown"
             text="↓ Pull down to refresh... ↓"
             width="100%"
             textAlign="center"
             paddingTop="{PADDING}"
             visible="false" />

    <s:Label id="_hintUp"
             text="↑ Release to refresh... ↑"
             width="100%"
             textAlign="center"
             paddingTop="{PADDING}"
             visible="false" />

</s:Application>