AS3中的DisplayObject有一个render事件,他会在重绘DisplayList之前触发,这给我们提供了在重绘之前最后一次操作的机会。
每次需要DisplayObject触发render事时,都要调用一次 stage.invalidate();
下面用一个小例子来说明一下具体用法把。
假设我们现在要写一个list组件,该组件有addItem()方法用于添加list项目,和remvoeItem() 方法用于删除list项目,当然还可能有addItemAt(),removeItemAt()等方法,这些方法调用后,都需要对list内的显示对象进行重新排列。
我们先实现一个List类,用于显示列表项目
List类中,有addItem() 和 removeItem() 这两个方法提供给外部调用,用于添加和删除list项目,这两个方法中除了将列表项目添加/删除,还要调用一个方法来重新对list中的项目进行排列,layoutContents()。
关键就是,这个layoutContents()的调用,他的调用次数越少,那效率当然就越高啦,如果是常规的做法,就是类似这样:
public function addItem(item:DisplayObject):void {
addChild(item);
layoutContents();
}
将item加入后,重新排列列表
下面是List类的源代码:
package {
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
public class List extends Sprite {
public function addItem(item:DisplayObject):void {
addChild(item);
layoutContents();
}
public function removeItem(item:DisplayObject):void {
if(contains(item)) {
removeChild(item);
layoutContents();
}
}
//对内部项目进行排列,可以是任意的排列算法
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;
}
}
}
这个程序粗看似乎没什么问题,但却存在一个效率问题
如果只调用一次addItem,没问题,如果调用10次呢? 前9次的layoutcontents()都不是必须的,只有第十次才是真正需要的这样程序的效率就降低了。
我们可以试一下
先需要一个简单的ListItem
package {
import flash.display.Shape;
public class ListItem extends Shape {
public function ListItem() {
super();
graphics.beginFill(0xFF6600);
graphics.drawRect(0, 0, 30, 16);
graphics.endFill();
}
}
}
AS3中的DisplayObject有一个render事件,他会在重绘DisplayList之前触发,这给我们提供了在重绘之前最后一次操作的机会。
每次需要DisplayObject触发render事时,都要调用一次 stage.invalidate();
下面用一个小例子来说明一下具体用法把。
假设我们现在要写一个list组件,该组件有addItem()方法用于添加list项目,和remvoeItem() 方法用于删除list项目,当然还可能有addItemAt(),removeItemAt()等方法,这些方法调用后,都需要对list内的显示对象进行重新排列。
我们先实现一个List类,用于显示列表项目
List类中,有addItem() 和 removeItem() 这两个方法提供给外部调用,用于添加和删除list项目,这两个方法中除了将列表项目添加/删除,还要调用一个方法来重新对list中的项目进行排列,layoutContents()。
关键就是,这个layoutContents()的调用,他的调用次数越少,那效率当然就越高啦,如果是常规的做法,就是类似这样:
public function addItem(item:DisplayObject):void { addChild(item); layoutContents(); }
将item加入后,重新排列列表
下面是List类的源代码:
package { import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; public class List extends Sprite { public function addItem(item:DisplayObject):void { addChild(item); layoutContents(); } public function removeItem(item:DisplayObject):void { if(contains(item)) { removeChild(item); layoutContents(); } } //对内部项目进行排列,可以是任意的排列算法 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; } } }
这个程序粗看似乎没什么问题,但却存在一个效率问题
如果只调用一次addItem,没问题,如果调用10次呢? 前9次的layoutcontents()都不是必须的,只有第十次才是真正需要的这样程序的效率就降低了。
我们可以试一下
先需要一个简单的ListItem
package { import flash.display.Shape; public class ListItem extends Shape { public function ListItem() { super(); graphics.beginFill(0xFF6600); graphics.drawRect(0, 0, 30, 16); graphics.endFill(); } } }
然后测试
package {
import flash.display.Sprite;
public class ListTest extends Sprite {
public function ListTest() {
var list:List = new List();
addChild(list);
list.addItem(new ListItem());
list.addItem(new ListItem());
list.addItem(new ListItem());
}
}
}
我们可以看到,输出了3次 do layout 说明layoutcontents执行了3次,前两次都是多余的。
现在,解决办法就是利用render事件啦。
因为在当前帧内,显示列表更新前会触发render事件,所以在render事件触发后来排列列表项目,就可以保证排列方法在做了任意次的添加或删除操作后只需调用一次,从而提高效率。
这么做只需要对List类稍做一些改动,首先肯定是要监听render事件,我们可以仅监听stage对象的render事件即可,因为这样以后可以做一个独立的RepaintManger来管理所有组件的重绘(可以参考AsWing的RepaintManager类)。
在render事件触发后,做我们需要的调整,由于要render事件触发,就必须先调用stage.invalidate() ,所以每次添加或删除list项目后,都要执行一次该方法,即:
[文章热度:]
上一页:AS3简单mp3播放器实例
下一页:AS3中的位运算操作