【问题标题】:flex mobile - performance of spark List with ItemRenderers that has large imageflex mobile - 使用具有大图像的 ItemRenderers 的 spark List 的性能
【发布时间】:2016-11-23 08:59:42
【问题描述】:
我正在 flex mobile 中开发带有大图像的 spark 列表。
每个 ItemRenderer 都有一个大图像。
像这样。
<s:ItemRenderer>
...
<s:BitmapImage source="{data.bmpData}" />
</s:ItemRenderer>
在dataProvider中,有名为“bmpData”的BitmapData。
问题在于滚动时的性能。
滚动时,渲染新图像时它会停止一段时间。
请帮帮我。
【问题讨论】:
标签:
list
actionscript-3
apache-flex
【解决方案1】:
如果问题是你同时渲染的位图数据太多,你可以在不同的帧中一一渲染。
这是一个例子。
制作自定义 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);
}
}
}