flex mobile - 使用具有大图像的ItemRenderers的spark列表

时间:2016-11-23 08:59:42

标签: list actionscript-3 flex

我正在开发flex mobile中带有大图像的spark列表。 每个ItemRenderer都有一个大图像。

像这样。

<s:ItemRenderer>
    ...
    <s:BitmapImage source="{data.bmpData}" />
</s:ItemRenderer>

在dataProvider中,BitmapData的名称为“bmpData”。

问题在于滚动时的性能。 在滚动时,它会在渲染新图像时停止一段时间。

请帮助我。

1 个答案:

答案 0 :(得分:1)

如果问题是你同时渲染太多的bitmapdata,你可以在不同的帧中逐个渲染它们。

这是一个例子。 制作自定义ItemRenderer

class YourItemRenderer
{

    override public function set data(value:Object):void
    {
         if (super.data != value)
         {
              super.data = value;

              yourBitmapImage.source  = null;

              //when the data change, don't call the render function directly
              EnterFrameManager.getInstance().addRenderFunction(render)
         }
    }

    private function render():void
    {
        if (yourBitmapImage != null && data != null)
        {
             yourBitmapImage.source = data.bmpData;
        }
    }
 }

EnterFrameManager用于控制渲染功能。

 class EnterFrameManager 
 {
        import mx.core.FlexGlobals;

        public function EnterFrameManager()
        {
             FlexGlobals.topLevelApplication.addEventListener( Event.EnterFrame, onEnterFrameHandler)         
        }

        private var _instance:EnterFrameManager;

        public static function getInstance():EnterFrameManager
        {

             if (_instance == null)
             {
                  _instance = new EnterFrameManager();
             }

             return instance;
        }

        //save the render functions
        private var renderQueue:Array = [];

        private var nowIntervalFrame:int = 0;

        //change it to small value when you don't feel lag
        private const UPDATE_INTERVAL_FRAMES:int = 6;

        private function onEnterFrameHandler(e:Event):void
        {
              nowIntervalFrame++;

              if (nowIntervalFrame >= UPDATE_INTERVAL_FRAMES)
              {
                  nowIntervalFrame = 0;

                  //change renderQueue by waitQueue
                  for each (var f:Function in waitQueue)
                  {   
                      addFunctionToQueue(f, renderQueue);
                  }

                  waitQueue.length = 0;

                  if (renderQueue.length > 0)
                  {
                      var f:Function = renderQueue.shift();

                      f();
                  }
              }
        }

        private var waitQueue:Array = [];

        public function addRenderFunction(f:Function):void
        {
            addFunctionToQueue(f, waitQueue);
        }

        private function addFunctionToQueue(f:Function, queue:Function):void
        {
           var index:int = queue.indexOf(f);

            if (index == -1)
            {
                 queue.push(f);
            }
            else
            {
                var temp:Function = queue.splice(index, 1);

                queue.push(temp);
            }
        }

 }