如何在flex中创建基于现有组件的自定义MXML组件,但在某些情况下在此现有组件上绘制叠加层。
理想情况下,新组件应基于(派生自)现有组件,以便现有组件的出现可以与新组件交换。
我尝试覆盖新组件中的updateDisplayList()并使用this.graphics绘制叠加层。这导致在现有组件的子项下面绘制叠加层。我还试图在收到渲染事件时进行绘图,这会导致类似的结果。
当应该触发叠加显示的外部条件发生变化时,我在新组件上调用invalidateDisplayList()。这适用于触发上述两种情况的绘图。剩下的问题似乎是弄清楚如何在添加后在所有其他组件之上绘制。
以下示例应说明我尝试做的事情;设置overlayEnabled并调用组件的invalidateDisplayList()方法时,红色矩形将在后台绘制....
// NewComponent.mxml
<ExistingComponent ...>
<mx:Script>
...
public var overlayEnabled:Boolean;
override protected updateDisplayList(...) {
super.updateDisplayList(...)
if (overlayEnabled) {
var g:Graphics = this.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
}
}
...
</mx:Script>
</ExistingComponent>
另外,请随意提出不同的方法。
答案 0 :(得分:4)
您必须为覆盖添加DisplayObject
并确保在致电updateDisplayList
时将其放在另一个的顶部。
public var overlayEnabled:Boolean;
public overlayHolder:(whatever display object you want to use)
override protected updateDisplayList(...) {
super.updateDisplayList(...)
if (overlayEnabled) {
if (overlayHolder.parent != this){
addChild(overlayHolder);
} else {
if (numChildren > 0)
setChildIndex(overlayHolder, numChildren-1);
}
var g:Graphics = overlayHolder.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
} else if (overlayHolder.parent == this) {
removeChild(overlayHolder);
}
}
修改强>
可用于将叠加层添加到显示列表的一个属性可以是rawchildren
:
package {
import flash.display.Graphics;
import flash.display.Sprite;
import mx.containers.VBox;
public class MyVBox extends VBox {
public var overlayEnabled : Boolean = true;
public var overlay : Sprite = new Sprite();
public function MyVBox() {
super();
}
protected override function updateDisplayList(unscaledWidth : Number, unscaledHeight : Number) : void {
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (overlayEnabled) {
if (overlay.parent != this) {
rawChildren.addChild(overlay);
} else {
if (rawChildren.numChildren > 0)
rawChildren.setChildIndex(overlay, rawChildren.numChildren - 1);
}
var g : Graphics = overlay.graphics;
g.beginFill(0xFF0000, 0.5);
g.drawRect(0, 0, width, height);
g.endFill();
} else if (overlay.parent == this) {
rawChildren.removeChild(overlay);
}
}
}
}