BitmapData.draw与spark.components.Label

时间:2011-08-12 15:15:49

标签: flex actionscript label bitmapdata

我在将Label组件绘制到BitmapData对象时遇到问题。无论我尝试什么,标签都不会出现。如果我只是将Label添加到显示列表,一切正常,但出于性能原因,这不是一个选项。我在将其他类型的东西(矢量艺术)绘制到BitmapData时没有遇到任何麻烦,但是这个标签真的让我陷入了循环。

我遇到了spark.components.Label和mx.controls.Label这个问题。我觉得这应该可行,因为这两个类都扩展了UIComponent,它实现了IBitmapDrawable,但我对Flex框架并不是很熟悉,所以也许我错过了一些东西。有人有什么想法吗?

我将分享我正在使用的相关Actionscript和CSS。

AS

    _label = new Label();
    _label.styleName = "categoryButton";
    _label.width = 500;
    _label.height = 40;
    _label.text = "LABEL TEXT";

    var bd:BitmapData = new BitmapData( 500, 500, true, 0 );
    bd.draw( _label );
    _labelBitmap = new Bitmap( bd );    

    addChild( _labelBitmap );

CSS:

    @font-face {
        src: url("assets/HelveticaNeueLTStd-Roman.otf");
        fontFamily: "HelveticaNeueLT-Roman";
        fontStyle: normal;
        fontWeight: normal;
        unicode-range: U+0020-U+0040, /* Punctuation, Numbers */
            U+0041-U+005A, /* Upper-Case A-Z */
            U+005B-U+0060, /* Punctuation and Symbols */
            U+0061-U+007A, /* Lower-Case a-z */
            U+007B-U+007E; /* Punctuation and Symbols */
        advancedAntiAliasing: true;
        embedAsCFF: true;
    }

    s|Label.categoryButton {
        fontFamily: "HelveticaNeueLT-Roman";
        font-size:30;
        fontStyle:normal;
        textAlign:center;
        color:#cc0000;
    }

2 个答案:

答案 0 :(得分:2)

当你绘制它,标签完全或只是文本时,现在会出现什么?如果您在标签上设置背景,那么会显示吗?

我不是百分百肯定,但我认为Flex的工作原理是失效。当您更改某些内容(例如,在初始化期间可能会多次更改)时,它只会设置一个标记,表示该组件需要在下一帧中重绘。在绘制之前尝试等待一两帧。

如果失败了,看到你只想要一张文字图片,请改用TextField,这应该更直接(将autoSize设置为TextFieldAutoSize.LEFT,你应该拥有与您的标签相同的行为)

答案 1 :(得分:2)

如您所料,这与Flex组件生命周期有关。看看UIComponent的源代码:

mx_internal function childAdded(child:DisplayObject):void {
    ...
    UIComponent(child).initialize();
    ...
}

在将子组件添加到父组件并因此添加到displaylist之后调用此方法。如您所见,只有这样才能初始化子组件。这意味着在将组件添加到displaylist之前不会绘制任何内容。

现在您可能会想:“好的,我们只需要显式调用initialize()。”这也行不通。看一下启动渲染的函数:

public function validateDisplayList():void
{        
    if (invalidateDisplayListFlag)
    {
        var sm:ISystemManager = parent as ISystemManager;

它指的是父DisplayObject,由于组件未添加到displaylist中,因此为null。之后还有其他事情会因为组件未正确创建而失败。只要组件不在显示列表中,Flex框架就永远不会调用此方法,如果您明确地调用它,则会出现运行时错误。

<强>结论: 如果要将Flex组件绘制为位图,则必须将它们添加到displaylist中。或者像@divillysausages建议并使用纯ActionScript替代方案。

为了确保组件已添加到displaylist并完全呈现,您应该监听FlexEvent.CREATION_COMPLETE事件(我认为跳过某些框架的建议是不好的做法;请参阅下面的评论)。

var label:Label = new Label();
label.text = "hello";
label.addEventListener(FlexEvent.CREATION_COMPLETE, nowDrawTheBitmap);
addElement(label);