在flex中动态地将子组件添加到Canvas vs Group

时间:2011-08-04 17:37:01

标签: flex actionscript

我有一个自定义组件,我在其中执行一些图形(例如绘制一条线)并动态添加子组件(例如标签)。

如果我将组件基于Group(根据文档推荐,因为它是一个spark组件),那么当我动态添加标签时,图形部分就会消失。

但是,如果我以Canvas为基础,这不会发生。

为什么会这样?

这是代码。

MyComponent.as

public class MyComponent extends Group
    {
        public var x1:int;
        public var y1:int;

        public function MyComponent()
        {
            super();

            addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void {
                x1 = mouseX;
                y1 = mouseY;
            });

            addEventListener(MouseEvent.MOUSE_MOVE, function(event:MouseEvent):void {
                if (event.buttonDown) {
                    graphics.lineStyle(3, 0x000000);
                    graphics.moveTo(x1, y1)
                    graphics.lineTo(mouseX, mouseY);
                    x1 = mouseX;
                    y1 = mouseY;
                }
            });
        }

        public function addLabel():void
        {
            var label:Label = new Label();
            label.x = 100;
            label.y = 100;
            label.text = "new label ";
            addElement(label);  //change to addChild if using Canvas 
        }
    }

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" 
               xmlns:local="*">

    <s:Panel width="50%" height="50%" verticalCenter="0" horizontalCenter="0" title="Sample app">

        <MyComponent id="drawingArea" xmlns="*" width="100%" height="100%" />

        <s:controlBarContent>
            <s:Button label="Add label" click="drawingArea.addLabel()"/>
        </s:controlBarContent>
    </s:Panel>
</s:Application>

2 个答案:

答案 0 :(得分:0)

这可能会为您提供一些额外的见解:

http://www.billdwhite.com/wordpress/?p=296

答案 1 :(得分:0)

根据组件生命周期在Flex中的工作原理,这是“正常的”。在您的函数中调用invalidateDisplayList时,它会重绘其中的所有内容并清除graphics。添加该标签时,它会失效。

如果我是你,我会做这样的事情:

public class MyComponent extends Group
{
    protected var _previousX:int;
    protected var _previousY:int;
    protected var _drawing:UIComponent;

    public function MyComponent()
    {
        super();
        this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
        this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
    }

    public function addLabel():void
    {
        var label:Label = new Label();
        label.x = 100;
        label.y = 100;
        label.text = "new label ";
        addElement(label);
    }

    override protected function createChildren():void
    {
        super.createChildren();
        if(!this._drawing)
        {
            this._drawing = new UIComponent();
            this._drawing.percentWidth = 100;
            this._drawing.percentHeight = 100;
            this.addElement(this._drawing);
        }
    }

    protected function onMouseDown(e:MouseEvent):void
    {
        this._previousX = e.localX;
        this._previousY = e.localY;
        this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
    }

    protected function onMouseUp(e:MouseEvent):void
    {
        this.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
    }

    protected function onMouseDown(e:MouseEvent):void
    {
        this._drawing.graphics.lineStyle(3, 0x000000);
        this._drawing.graphics.moveTo(this._previousX, this._previousY);
        this._drawing.graphics.lineTo(e.localX, e.localY);
        this._previousX = e.localX;
        this._previousY = e.localY;
    }
}

这是未经测试的,但我认为你明白了。您还应该阅读组件生命周期并真正考虑通过尝试将其抽象为数据来尝试实现的行为(我不是'addLabel'函数的粉丝,例如:P)。