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

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

问题描述

如何在flex中创建一个基于现有组件的自定义MXML组件,但是在某些情况下会在此现有组件上绘制一个覆盖。理想情况下,新组件应基于(派生)退出组件,以便现有组件的出现可以换出新的组件。



我试图覆盖updateDisplayList ()在新的组件,并使用this.graphics绘制覆盖。这导致覆盖层被绘制在现有组件的子项下面。我也试图在收到一个导致相似结果的渲染事件时进行绘制。



当触发叠加层显示的外部条件发生变化时,我的新组件上的invalidateDisplayList()。这可以触发上述两种情况下的绘图。剩下的问题似乎是要想出如何在添加所有其他组件时绘制其他组件。

下面的例子应该说明我试图做的事情;当设置了overlayEnabled,并调用了组件的invalidateDisplayList()方法时,红色的矩形会在后台被绘制出来。

  // NewComponent.mxml 
< ExistingComponent ...>
< mx:Script>
...

public var overlayEnabled:Boolean;

覆盖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>

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

解决方案

您必须添加一个 DisplayObject 覆盖,并确保当您调用 updateDisplayList code>它位于另一个顶部。

  public var overlayEnabled:Boolean; 

public overlayHolder :(无论你想使用什么显示对象)

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

 包{
import flash.display.Graphics;
import flash.display.Sprite;

导入mx.containers.VBox;

public class MyVBox extends VBox {
public var overlayEnabled:Boolean = true;
public var overlay:Sprite = new Sprite();

public function MyVBox(){
super();

$ b保护覆盖函数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);
}
}
}
}


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.

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.

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.

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.

解决方案

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

Edit: 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);
            }
        }
    }
}

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

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