现在,解决办法就是利用render事件啦。
因为在当前帧内,显示列表更新前会触发render事件,所以在render事件触发后来排列列表项目,就可以保证排列方法在做了任意次的添加或删除操作后只需调用一次,从而提高效率。
这么做只需要对List类稍做一些改动,首先肯定是要监听render事件,我们可以仅监听stage对象的render事件即可,因为这样以后可以做一个独立的RepaintManger来管理所有组件的重绘(可以参考AsWing的RepaintManager类)。
在render事件触发后,做我们需要的调整,由于要render事件触发,就必须先调用stage.invalidate() ,所以每次添加或删除list项目后,都要执行一次该方法,即:
代码:
public function addItem(item:DisplayObject):voide {
......
stage.invalidate()
}
由于是监听的stage的render事件,所以在添加删除操作后,要做一个标记,表示list有改动,需要在render事件后重新排列,如果该标记为false,那么即使render触发了也不做排列,因为stage的render事件也有可能是由于该stage内的其他child需要重绘而造成stage的render触发。
下面是改过后的List代码
代码:
package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
public class List extends Sprite {
private var changed:Boolean;
public function List() {
super();
addEventListener(Event.ADDED_TO_STAGE, __addToStage);
}
public function addItem(item:DisplayObject):void {
addChild(item);
requireLayout();
}
public function removeItem(item:DisplayObject):void {
if(contains(item)) {
removeChild(item);
requireLayout();
}
}
private function requireLayout():void {
changed = true;
if(stage != null) stage.invalidate();
}
//对内部项目进行排列,可以是任意的排列算法
protected function layoutContents():void {
trace("do layout");
var y:Number = 0;
var num:int = numChildren;
for(var i:int=0; i<num; i++) {
var child:DisplayObject = getChildAt(i);
child.x = 0;
child.y = y;
y += child.height+2;
}
}
private function __addToStage(e:Event):void {
stage.addEventListener(Event.RENDER, __render);
if(changed) stage.invalidate();
}
private function __render(e:Event):void {
if(changed) {
layoutContents();
changed = false;
}
}
}
}
当我们再次运行ListTest的时候,do layout 只输出了一次。
就是这些内容,当然,你可能会说,需要做到这些根本不需要这么复杂,只要公开layoutContents方法,在所有操作调用之后让调用者自行调用一次layoutContents()。
在这个例子中当然可以,但是当情况很复杂的时候,使用者每进行一次操作都要自行调用更新的方法,这样做并不是好的解决方案。试想,如果flashplayer不会为我们处理显示DisplayObject的工作,而是每次addChild/removeChild之后,我们都需要自行调用flashplayer底层的方法来让我们需要的东西显示出来,这样做显然很不好。
完了,就这些东东,写完之后俺感觉自己的表达能力不好,如果觉得我说的很模糊,那就研究下代码吧,全部代码都在上面了,欢迎指教和讨论 ^^
共2页: 上一页12下一页
上一篇:
AS3.0的Socket通讯发送固定字符串(指定编码) 下一篇:
使用As3.0的50个理由