【问题标题】:width of spark label火花标签的宽度
【发布时间】:2011-08-05 16:18:33
【问题描述】:

我需要设置火花标签的文本,然后根据其宽度沿 x 轴放置此类标签。不幸的是,标签的宽度似乎不会立即更新,因此定位会失败。我可以监听标签上的 updateComplete 事件并更新它的位置,但这意味着重新定位标签的频率比我想要的要高得多(updateComplete 触发的频率比改变宽度的频率高得多)。关于如何正确处理看似微不足道的任务的任何想法?

这是一个代码 sn-p,它显示了我上面描述的内容。如果按下按钮,您将看到 3 条轨迹:更改其文本之前的标签宽度、设置其文本之后以及标签完成自我更新时。很想知道是否有办法获得正确的宽度而不必听 updateComplete 事件...按钮和 VGroups 只是为了运行示例

<?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" minWidth="955" minHeight="600">

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            protected function button1_clickHandler(event:MouseEvent):void
            {
                trace("label width = ", lb.width);
                lb.addEventListener(FlexEvent.UPDATE_COMPLETE, lb_updateCompleteHandler);
                lb.text = "hello world!";
                trace("label width post change= ", lb.width);
            }

            protected function lb_updateCompleteHandler(event:FlexEvent):void
            {
                lb.removeEventListener(FlexEvent.UPDATE_COMPLETE, lb_updateCompleteHandler);
                trace("label width post update complete = ", lb.width);
            }

        ]]>
    </fx:Script>

    <s:VGroup>
        <s:Button label="go" click="button1_clickHandler(event)"/>
        <s:Label id="lb" text="h" x="10" y="10" />
    </s:VGroup>

</s:Application>

【问题讨论】:

  • 我不明白你想要的布局,你能试着用不同的词来解释你希望事物如何出现,以及它们实际上是如何出现的吗?
  • 我希望标签有一个取决于其宽度的 x 位置。这有点笼统,但我希望并不难想象......
  • 您到底想达到什么目的?我的意思是:最终结果应该是什么样子?也许您可以发布屏幕截图。我有一种感觉,你正在努力做某事,但我不知道。
  • 我认为你是对的,我正在努力做事,偶然发现了一个我认为是关于标签的有趣的通用问题。最终目标:我有一个标签需要放在一堆其他东西的左边。标签可以改变长度,东西可以增长或缩小。我想 HGroup 会为我处理业务,但我试图远离自动布局(我正在优化一些项目渲染器)并认为我可以自己处理标签的定位(不应该那样毕竟很难)。感谢您的帮助!
  • 如果你在讨论项目渲染器的优化,你最好编写自己的基于 ActionScript 的项目渲染器,其中 mx.core.UIFTETextFieldmx.core.UITextField 位于 updateDisplayList() 中。

标签: apache-flex


【解决方案1】:

以下内容对我有用。简单而有效。

var l:Label = new Label();
l.text = "That'll do";
var tlm:TextLineMetrics = l.measureText( l.text);
Alert.show( tlm.width + " is what you are looking for");

【讨论】:

    【解决方案2】:

    VGroupGroupVerticalLayout。它不允许在组内进行自定义定位(使用xy)。要获得这种可能性,请使用 Group 和(默认)BasicLayout

    【讨论】:

    • 对不起 - VGroup 与问题无关,它只是一种独立定位按钮和标签的方法。将编辑这个问题 - 我显然写得不好:-)
    【解决方案3】:

    如果您使用callLater(),您可以“捕获”当前范围内的变量,但也可以在width 中的更改传播后执行。例如:

    callLater(function():void
          {
            trace("label width in callLater = ", lb.width);
          });
    

    更新:我认为我应该详细说明一下,以明确我所说的“捕获”值的含义。这可以通过以下简单的插图来完成:

    callLater(function(prevWidth:Number):void
          {
            trace("previous label width in callLater = ", prevWidth);  // 8
            trace("label width in callLater = ", lb.width);  // 64
          }, [lb.width]);
    

    如示例所示,您通过 args 数组传入的参数(即,变为 prevWidth[lb.width])采用当前值(即,它们按值传递),而,您在函数中直接引用的变量实际上是在函数执行时的范围内(即closure)。

    您也可以使用事件侦听器来执行此操作,但使用 callLater() 会更简单一些。

    【讨论】:

      【解决方案4】:

      看起来听 resize 事件可以解决问题,并且不像 updateComplete 事件那样通用,所以我称之为“正确答案”。由于性能优化,当您尝试手动定位东西时,可能有更好的方法来做到这一点,尽管我还不确定它是什么。

      【讨论】:

        【解决方案5】:

        您可以在设置文本后调用 lb.validateNow(),这样您将立即获得新的宽度。但建议您阅读有关组件生命周期的内容,不要有这些琐碎的问题。

        是的,正如人们已经指出的那样,这种布局无法重新定位。

        【讨论】:

        • 我曾尝试过 validateNow,但令人惊讶的是,在这种情况下似乎没有奏效——不知道为什么。正如我在重新编辑中提到的那样,布局与问题无关......
        猜你喜欢
        • 2011-12-26
        • 1970-01-01
        • 2017-05-19
        • 2014-01-29
        • 1970-01-01
        • 2015-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多