2012-07-18 49 views
0

想象一下,平板電腦應用程序並排顯示兩個內容區域。它們完全填充顯示屏,所以高度爲100%,寬度爲50%。讓我們假設我們爲一個容器添加一個列表。當然,這個列表將消耗整個顯示器的一半空間。Flex移動 - 增加列表滾動性能

現在我的問題是,有可能高的幀率滾動是不可能的這種大小的列表?我有最基本的AS3 ItemRenderer,並且在滾動期間仍然不能獲得高於30fps的任何東西。現在奇怪的是,如果我添加了其他容器的東西,可以說另一個列表或其他組件,則列表滾動性能會下降到20幾歲。 因此,在40+ fps附近沒有任何東西可以在他們的MAX節目中看到Adobe廣告。

我在iPad2和3上測試,甚至使用靜態值進行測試,滾動效果並不好。現在,如果啓用流式傳輸值以便調用ItemRenderer的set data方法,則幀速率會再下降2到3幀。

我的(幾乎)完整的渲染器看起來是這樣,但即使我剝它只是顯示一個文本框,禁用的東西在set data回事,也可以設置僅單個文本框的大小在layoutContents,性能如上所述,如果單獨顯示列表大約爲30,如果顯示其他內容,則低20s。

//FCStyleableTextField is just a StyleableTextField with an additional ID 

    private var _textFields:Vector.<FCStyleableTextField>; 
    private var _oldValues:Dictionary; 
    private var _sym:Symbol; 

    public function GridRenderer() { 
     super(); 
     _textFields = new Vector.<FCStyleableTextField>(); 
     _oldValues = new Dictionary(); 
    } 

    override protected function createChildren():void { 

     var _symLabel:FCStyleableTextField = new FCStyleableTextField(); 
     _symLabel.editable = false; 
     _symLabel.selectable = false; 
     _symLabel.multiline = false; 
     _symLabel.id="sym"; 
     _symLabel.setStyle("fontSize", fontSize); 
     _symLabel.textColor = 0xc0c0c0; 
     _textFields.push(_symLabel); 
     addChild(_symLabel); 

     var fidLen:int = fids.length; 
     for (var i:int = 0; i<fidLen; i++) { 
      var _fid_lbl:FCStyleableTextField = new FCStyleableTextField(); 
      _fid_lbl.selectable = false; 
      _fid_lbl.editable = false; 
      _fid_lbl.multiline = false; 
      _fid_lbl.id = String(fids[i]); 
      _fid_lbl.textColor = 0xc0c0c0; 
      _fid_lbl.setStyle("textAlign", "right"); 
      _fid_lbl.setStyle("fontSize", fontSize); 
      _fid_lbl.text = " "; 
      _textFields.push(_fid_lbl); 
      addChild(_fid_lbl); 

      if(i>visibleColumns) { 
       _fid_lbl.includeInLayout = false; 
       _fid_lbl.visible = false; 
      } 
     } 
    } 


    override public function set data(value:Object):void { 
     if(!value) return; 

     if(data) { 
      // check if the value's symbolName is different than the current 
      // data's symbolName, if so, the itemRenderer has been 
      // recycled, thus we need to reset the old fid values 
      if((value as Symbol).symbolName != (data as Symbol).symbolName) 
       _oldValues = new Dictionary(); 
     } 

     super.data = value; 

     _sym = data as Symbol; 

     try { 
      var textLen:int = _textFields.length; 
      for (var i:int = 0; i<textLen;i++) { 
       var lbl:FCStyleableTextField = _textFields[i]; 
       if(lbl.id == "sym") { 
        lbl.text = _sym.symbolName; 
        lbl.truncateToFit(); 
       } else { 
        if(lbl.id == _sym.fidList.fidMap[lbl.id].fidId && lbl.text != _sym.fidList.fidMap[lbl.id].fieldValue) { 
         var time:int = new Date().time; 
         var timerName:String = _sym.symbolName+","+lbl.id+","+grid; 
         globalTimer.addTimer(timerName, time, "reset", lbl, null, null); 

         var _oldVal:* = _oldValues[lbl.id]; 
         var _newVal:* = _sym.fidList.fidMap[lbl.id].fieldValue; 

         // basic color formatting 
         if(Number(_newVal) > Number(_oldVal)) 
          lbl.textColor = 0x40c040; 
         else if(Number(_newVal) < Number(_oldVal)) 
          lbl.textColor = 0xf05050; 

         // add + to change and changePercent fids if value is positive 
         if(lbl.id == "56") { 
          if(_newVal >0) 
           lbl.text = "+" + _newVal; 
          else 
           lbl.text = String(_newVal); 
         } else if(lbl.id == "11") { 
          if(_newVal >0) 
           lbl.text = "+" + _newVal; 
          else 
           lbl.text = String(_newVal); 
         } else 
          lbl.text = String(_newVal); 

         if(!_sym.fidList.fidMap[lbl.id].fieldValue) 
          lbl.text =" "; 

         _oldValues[lbl.id] = _newVal; 
        } 
       } 

       lbl.truncateToFit(); 
      }  
     } catch (e:Error) { /* nothing to do here -> try/catch required due to async symbolassembly */ } 
    } 

    override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void { 
     var viewWidth:Number = unscaledWidth - paddingLeft - paddingRight; 
     var viewHeight:Number = unscaledHeight - paddingTop - paddingBottom; 
     var _previousLabel:FCStyleableTextField; 
     var textLen:int = _textFields.length; 

     for(var i:int =0; i<textLen;i++) { 
      var lbl:FCStyleableTextField = _textFields[i]; 
      graphics.beginFill(0x808080, .3); 
      lbl.height = viewHeight; 
      lbl.y = paddingTop; 

      if(lbl.id=="sym") { 
       lbl.width = 95; 
      } else if (lbl.id == "35000") { 
       lbl.width = 24; 
      } else { 
       lbl.width = optimalColWidth; 
      } 

      _previousLabel ? lbl.x = (_previousLabel.x + _previousLabel.width): lbl.x = paddingLeft; 
      graphics.drawRect(lbl.x+lbl.width, 1, 1, unscaledHeight-1); 

      lbl.commitStyles(); 
      _previousLabel = lbl; 
      graphics.endFill(); 
     } 
    } 

不過,我敢肯定,它不是項目渲染導致增速放緩,原因正如我所說的,它的成本2,也許3幀相比,顯示只是一個單一的文本框的呈現。 我寧願以爲Flex無法處理一次顯示的向量的數量,是這樣的可能嗎?有什麼方法可以提高性能? 當用戶滾動列表時,我已經禁用了直播流數值,因此flex基本上只需滾動位圖(因爲LabelItemRenderer會自動啓用cacheasbitmap),但增加的可能是4幀。 你的傢伙做什麼技巧讓滾動更順暢?

+0

http://evtimmy.com/2011/10/424/ - 你檢查這介紹? – 2012-07-18 15:10:17

+0

我不確定這個問題是否具體回答。你如何評估滾動的幀率? – JeffryHouser 2012-07-18 15:16:24

+0

@AlexanderFarber,是的,我有。那是我剛纔講的MAX節目的幻燈片。基本上沒有什麼新東西,也沒有我在渲染器中沒有考慮(和實現)的內容,例如緩存。 – AlBirdie 2012-07-18 15:23:00

回答

1

找出使用setElementSize()setElementPosition()代替使用寬度/高度和x/y有很大區別。初始滾動性能達到3fps,每個項目已渲染8fps。 所以我現在已經接近30fps了,仍然不能接近你用原生應用程序做的事情,但我認爲這與Flex和如此龐大的渲染器一樣好。

也被禁止,實時更新,使得渲染器不需要再緩存爲位圖時更新進來