Измените размер spark.components.Label в зависимости от его содержимого и найдите его размеры. - PullRequest
1 голос
/ 21 октября 2011

Я портирую флеш-игру на Flex.

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

    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, однако я не знаю, как найти размеры Label и как его увеличить с текстом.

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

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

enter image description here

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) Используйте и добавьте к нему мой собственный TextField

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

1 Ответ

2 голосов
/ 22 октября 2011

Вам придется немного изменить свое представление о макетах, если вы используете 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" />

...