Измените размер spark.components.Label в зависимости от его содержимого и найдите его размеры.

Я портирую Flash-игру на Flex.

В оригинальной Flash-игре, когда игрок что-то болтал, я назначал этот текст текстовому полю (которое имело заданную ширину W=240 и wordWrap=true, wordWrap=true, >многострочный=true). После этого я использую textHeight TextField, чтобы нарисовать прямоугольник вокруг него (и под ним):

    public function set text(str:String):void {
        _tf.text = str;
        _tf.height = _tf.textHeight + 2 * PAD;

        // draw the rectangle around the TextField
        _rect.x = _tf.x - PAD;
        _rect.y = _tf.y - PAD;
        _rect.graphics.clear();
        _rect.graphics.beginFill(BGCOLOR, 0.8);
        _rect.graphics.drawRoundRect(0, 0, _tf.textWidth + 2 * PAD, _tf.textHeight + 2 * PAD, R); 
        _rect.graphics.endFill();

        _fadeTimer.reset();
        _fadeTimer.start();
    }

Это работает нормально.

Однако в моем новом приложении Flex я не знаю, как найти Ярлык и как сделать так, чтобы он увеличивался вместе с текстом.

Вот мой тестовый пример, который работает не так, как хотелось бы (но работает в Flash Builder нормально).

У кого-нибудь есть предложения, я много искал.

введите здесь описание изображения

BubbleTest.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:comps="*"
    width="700" height="525" backgroundColor="#CCCCCC"
    creationComplete="init()">

    <fx:Script>
        <![CDATA[
            public function init():void {
                _bubble0.text = 'Hello world';
            }       
        ]]>
    </fx:Script>

    <s:Rect id="_user0" horizontalCenter="0" y="340" width="160" height="140">
        <s:stroke>
            <s:SolidColorStroke color="red" />
        </s:stroke> 
    </s:Rect>

    <s:Rect id="_user1" left="4" top="4" width="160" height="140">
        <s:stroke>
            <s:SolidColorStroke color="red" />
        </s:stroke> 
    </s:Rect>

    <s:Rect id="_user2" right="4" top="4" width="160" height="140">
        <s:stroke>
            <s:SolidColorStroke color="red" />
        </s:stroke> 
    </s:Rect>

    <comps:Bubble id="_bubble0" x="20" y="340" />
    <comps:Bubble id="_bubble1" left="170" top="4" />
    <comps:Bubble id="_bubble2" right="170" top="4" />

</s:Application>

Bubble.mxml:

<?xml version="1.0" encoding="utf-8"?>
<s:Group 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:s="library://ns.adobe.com/flex/spark" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    creationComplete="init(event)">

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            public static const W:uint = 240;
            private static const R:uint = 6;
            private static const PAD:uint = 4;
            private static const BGCOLOR:uint = 0xCCFFCC;

            private var _timer:Timer = new Timer(500, 20);

            public function init(event:FlexEvent):void {
                _timer.addEventListener(TimerEvent.TIMER, fadeBubble);
                _timer.addEventListener(TimerEvent.TIMER_COMPLETE, hideBubble);
                addEventListener(MouseEvent.CLICK, hideBubble);

                if (x > 100 && x < 200) {
                    _left.visible = true;
                    _right.visible = false;
                } else {
                    _left.visible = false;
                    _right.visible = true;
                }
            }

            public function set text(str:String):void {
                _text.setStyle('color', Util.isRed(str) ? 0xFF0000 : 0x000000);
                _text.text = str;

                // XXX resize _rect here, but how?

                _timer.reset();
                _timer.start();
            }


            public function get text():String {
                return _text.text;
            }

            private function fadeBubble(event:TimerEvent):void {
                if (_timer.currentCount * 2 > _timer.repeatCount)
                    alpha /= 2;
            }

            public function hideBubble(event:MouseEvent):void {
                visible = false;
                _timer.stop();
            }           
        ]]>
    </fx:Script>

    <s:Graphic id="_right" x="{W}" y="0">
        <s:Path data="L 0 10 
                L 20 20 
                L 0 30">
            <s:fill>
                <s:SolidColor color="{BGCOLOR}" />
            </s:fill>
        </s:Path>
    </s:Graphic>

    <s:Graphic id="_left" x="0" y="0">
        <s:Path data="L 0 10 
                L -20 20 
                L 0 30">
            <s:fill>
                <s:SolidColor color="{BGCOLOR}" />
            </s:fill>
        </s:Path>
    </s:Graphic>

    <s:Rect id="_rect" x="0" y="0" width="{W}" height="120" radiusX="{R}" radiusY="{R}">
        <s:fill>
            <s:SolidColor color="{BGCOLOR}" />
        </s:fill>
    </s:Rect>

    <s:Label id="_text" x="0" y="75" width="{W}" fontSize="16" textAlign="center" />
</s:Group>

Пока у меня только 2 идеи:

1) Каким-то образом получить mx_internal TextField от Label

import mx.core.mx_internal;
use namespace mx_internal;
// XXX and then?

2) Используйте ‹mx:UIComponent id="uic"/› и добавьте к нему мой собственный TextField()

а может есть более безболезненные способы?


person Alexander Farber    schedule 21.10.2011    source источник


Ответы (1)


Вам придется немного изменить свое представление о макетах, если вы используете flex. То, что вы хотите сделать, это установить ширину прямоугольников в процентах и ​​установить абсолютную ширину ни на что. Это позволяет макету делать то, что называется «Размер по содержимому», что означает, что его ширина будет определяться его дочерними элементами. Затем элементы, которые используют ширину в процентах, будут смотреть на это значение и размещать себя. Немного сложно объяснить словами, поэтому я вставил сюда новый файл Bubble.mxml, чтобы вы могли его посмотреть. Вероятно, это не совсем тот вид, который вам нужен, но это должно помочь вам начать работу, и вам потребуется лишь небольшая настройка, чтобы получить именно то, что вы хотите.

<?xml version="1.0" encoding="utf-8"?>

<fx:Script>
    <![CDATA[
        import mx.events.FlexEvent;

        //public static const W:uint = 240;
        private static const R:uint = 6;
        private static const PAD:uint = 4;
        private static const BGCOLOR:uint = 0xCCFFCC;

        private var _timer:Timer = new Timer(500, 20);

        public function init(event:FlexEvent):void {
            _timer.addEventListener(TimerEvent.TIMER, fadeBubble);
            _timer.addEventListener(TimerEvent.TIMER_COMPLETE, hideBubble);
            addEventListener(MouseEvent.CLICK, hideBubble);

            if (x > 100 && x < 200) {
                _left.visible = true;
                _right.visible = false;
            } else {
                _left.visible = false;
                _right.visible = true;
            }
        }

        public function set text(str:String):void {
            //_text.setStyle('color', Util.isRed(str) ? 0xFF0000 : 0x000000);
            _text.text = str;

            // XXX resize _rect here, but how?

            _timer.reset();
            _timer.start();
        }


        public function get text():String {
            return _text.text;
        }

        private function fadeBubble(event:TimerEvent):void {
            if (_timer.currentCount * 2 > _timer.repeatCount)
                alpha /= 2;
        }

        public function hideBubble(event:MouseEvent):void {
            visible = false;
            _timer.stop();
        }           
    ]]>
</fx:Script>

<s:Graphic id="_right">
    <s:Path data="L 0 10 
            L 20 20 
            L 0 30">
        <s:fill>
            <s:SolidColor color="{BGCOLOR}" />
        </s:fill>
    </s:Path>
</s:Graphic>

<s:Graphic id="_left" x="0" y="0">
    <s:Path data="L 0 10 
            L -20 20 
            L 0 30">
        <s:fill>
            <s:SolidColor color="{BGCOLOR}" />
        </s:fill>
    </s:Path>
</s:Graphic>

<s:Rect id="_rect" x="0" y="0" width="100%" height="100%" radiusX="{R}" radiusY="{R}">
    <s:fill>
        <s:SolidColor color="{BGCOLOR}" />
    </s:fill>
</s:Rect>

<s:Label id="_text" x="0" paddingTop="5" paddingBottom="5" fontSize="16" textAlign="center" />

person Greg    schedule 22.10.2011
comment
Спасибо, Грег, я понял твою мысль. Моя единственная проблема заключается в слишком коротких строках, таких как «Да» и «Нет». В моей программе Flash я использую TextField.textWidth, но во Flex - ??? - person Alexander Farber; 22.10.2011
comment
Не должно иметь значения, но может случиться так, что вы нажмете настройку minWidth по умолчанию. На вашей метке искры попробуйте установить minWidth = 0. - person Greg; 25.10.2011