BitmapData.draw с помощью spark.components.Label - PullRequest
1 голос
/ 12 августа 2011

У меня проблемы с отрисовкой компонента Label для объекта BitmapData. Независимо от того, что я пытаюсь, лейбл никогда не появляется. Все работает нормально, если я просто добавляю метку в список отображения, но по соображениям производительности это не вариант. У меня нет проблем с рисованием других вещей (векторной графики) в 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 ]

2 голосов
/ 12 августа 2011

Как вы и предполагали, это связано с жизненным циклом компонента Flex.Взгляните на исходный код UIComponent:

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

Этот метод вызывается после добавления дочернего компонента в родительский компонент и, следовательно, в список отображения.Как видите, только тогда будет инициализирован дочерний компонент.Это означает, что ничего не будет нарисовано до тех пор, пока компонент не будет добавлен в список отображения.

Теперь вы можете подумать: «Хорошо, давайте тогда просто вызовем initialize () явно».Это тоже не сработает.Посмотрите на функцию, которая инициирует рендеринг:

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

Это относится к родительскому DisplayObject, который является нулевым, так как компонент не был добавлен в список отображения.И есть другие вещи после этого, которые потерпят неудачу, потому что компонент не был создан должным образом.Платформа Flex никогда не вызовет этот метод, если компонент отсутствует в списке отображения, и если вы вызовете его явно, вы получите ошибки времени выполнения.

Вывод: , если вы хотитеНарисуйте компоненты Flex в виде растрового изображения, вам придется добавить их в список отображения.Или сделайте так, как предложил @divillysausages, и используйте чистую альтернативу ActionScript.

Чтобы быть уверенным, что компонент был добавлен в список отображения и полностью отображен, вы должны прослушать событие FlexEvent.CREATION_COMPLETE (я считаю, предложение пропуститьнекоторые кадры - плохая практика; см. комментарии ниже).

var label:Label = new Label();
label.text = "hello";
label.addEventListener(FlexEvent.CREATION_COMPLETE, nowDrawTheBitmap);
addElement(label);
2 голосов
/ 12 августа 2011

Что теперь появляется, когда вы рисуете его, полностью метку или только текст? Если вы установите фон на этикетке, он появится?

Я не уверен на 100%, но я думаю, что Flex работает по принципу аннулирования. Когда вы изменяете что-то (что может измениться несколько раз во время инициализации, например), он просто устанавливает флаг, что компонент должен быть перерисован в следующем кадре. Попробуйте подождать кадр или два, прежде чем рисовать его.

Если это не удастся, поскольку вы просто хотите получить изображение текста, используйте вместо него TextField, который должен быть более немедленным (установите autoSize на TextFieldAutoSize.LEFT, и вы должны вести себя так же, как ваш ярлык)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...