2

如何在 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>

此外,请随时提出不同的方法。

4

1 回答 1

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);
            }
        }
    }
}
于 2010-01-29T17:34:55.087 回答