在自定义flex组件中绘制叠加层

时间:2010-01-29 17:20:55

标签: flex custom-component

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

另外,请随意提出不同的方法。

1 个答案:

答案 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);
            }
        }
    }
}