Apache flex 在自定义flex组件中绘制覆盖

Apache flex 在自定义flex组件中绘制覆盖,apache-flex,custom-component,Apache Flex,Custom Component,如何在flex中创建一个自定义MXML组件,该组件基于现有组件,但在某些情况下会在现有组件上绘制一个覆盖 理想情况下,新组件应该基于(派生自)现有组件,以便现有组件的引用可以与新组件交换 我尝试在新组件中覆盖updateDisplayList(),并使用this.graphics绘制覆盖。这导致覆盖在现有零部件的子项下绘制。我还尝试在收到一个渲染事件后进行绘制,该事件会导致类似的结果 当触发覆盖显示的外部条件发生变化时,我在新组件上调用invalidateDisplayList()。这将触发上述

如何在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>
//NewComponent.mxml
...
可覆盖的公共变量:布尔值;
覆盖受保护的updateDisplayList(…){
super.updateDisplayList(…)
如果(覆盖){
var g:Graphics=this.Graphics;
g、 Beginull(0xFF0000,0.5);
g、 drawRect(0,0,宽度,高度);
g、 endFill();
}
}
...

另外,请随意建议不同的方法。

您必须为您添加一个
显示对象
,并确保在调用
更新显示列表
时,该对象位于另一个对象的顶部

        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);
            }
        }
编辑: 可以使用以下属性将覆盖添加到显示列表中:


好的,我知道你要去。。。在这种情况下,现有组件基于VBox。因此,它希望(a)垂直布局使用addChild()添加的所有内容,(b)需要添加的DisplayObject来实现IUIComponent。(b) 还不算太坏,;但是我怎样才能把我的DisplayObject添加到上面呢?我必须做一些测试,我想你不能在你的VBox和覆盖中使用画布?这是非常有希望的。。。我正在路上,不能马上试试。可能要到星期一我才能查出来,但我会尽快让你知道的。谢谢你的帮助!是的。孩子们真的做到了。也不需要查看updateDisplayList。我可以在需要时添加覆盖层。在我的例子中,将覆盖的mouseEnabled属性设置为false也有帮助。谢谢
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);
            }
        }
    }
}