2013-02-22 4 views
0

Попытка реализовать «pull up to refresh» Я создал следующий простой тестовый код (просто добавьте в новый проект Flash Builder, "пустой" шаблон, то есть без навигационной панели):Spark List в мобильном приложении Flex: снимите, чтобы обновить - с помощью тестового кода и скриншота

Скриншот:

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() вызова выше (имитирующие выборки данных с веб-сервера) - все ломается, то hint.visible=true создается снова и снова и _list мерцает.

Есть ли у кого-нибудь просьба, как исправить мой недостаток , чтобы обновить?

+1

это возможно что при добавлении элементов в arraycollection влияет на значение/положение прокрутки? Это могло бы (возможно) снова вызвать «handleScroll» - таким образом, мерцание? – ethrbunny

+0

Возможно ... Любые предложения, как это сделать? –

+1

Возможно, вы можете отключить arraycollection от своего вида, пока вы его обновите. Или загрузите его в новый ac, а затем замените их после того, как все дополнительные данные были вставлены. – ethrbunny

ответ

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>