在自定义 flex 组件中绘制叠加层 [英] Drawing an overlay in custom flex component

查看:30
本文介绍了在自定义 flex 组件中绘制叠加层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在 flex 中创建自定义 MXML 组件,该组件基于现有组件,但在某些情况下会在此现有组件上绘制叠加层.

How would one create a custom MXML component in flex which is based on an existing component but draws an overlay over this existing component in certain situations.

理想情况下,新组件应该基于(派生自)现有组件,以便可以用新组件替换现有组件的出现.

Ideally, the new component should be based on (derive from) the exiting component so that occurrences of the existing component could just be swapped out with the new one.

我尝试在新组件中覆盖 updateDisplayList() 并使用 this.graphics 绘制叠加层.这导致覆盖被绘制在现有组件的子组件之下.我还尝试在接收到导致类似结果的渲染事件时进行绘图.

I tried to override updateDisplayList() in the new component and to paint the overlay using this.graphics. This resulted in the overlay being drawn underneath the children of the existing component. I also tried to do the drawing upon receiving a render-event which lead to similar results.

当触发覆盖层显示的外部条件发生变化时,我会在我的新组件上调用 invalidateDisplayList().这适用于触发上述两种情况的绘图.剩下的问题似乎是弄清楚如何在添加所有其他组件后绘制它们.

When the external condition which should trigger the display of the overlay changes, I call invalidateDisplayList() on my new component. That works to trigger the drawing for both cases described above. The remaining problem seems to be to figure out how to draw on top of all the other components once they are added.

下面的例子应该说明我试图做的事情;当设置overlayEnabled并调用组件的invalidateDisplayList()方法时,红色矩形将被绘制在背景中......

The following example should illustrate what I tried to do; when overlayEnabled was set and the component's invalidateDisplayList() method was called, the red rectangle would get painted in the background....

// 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>

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

Also, feel free to suggest different approaches.

推荐答案

你必须添加一个 DisplayObject 为你覆盖并确保当你调用 updateDisplayList 时它是放在另一个的顶部.

You will have to add a DisplayObject for you overlay and insure when you call updateDisplayList that it is place on the top of the other.

        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:

One property you can use to add your overlay to the display list can be the 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);
            }
        }
    }
}

这篇关于在自定义 flex 组件中绘制叠加层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆