【问题标题】:how to find height of dynamic flex component used as a popup如何查找用作弹出窗口的动态 flex 组件的高度
【发布时间】:2011-10-01 00:35:40
【问题描述】:

我创建了一个自定义组件,其中包含几个用作工具提示的内联项呈现器。组件的高度未知,因为组件的数据内容直到运行时才知道。

但是,在显示工具提示时,有时它会超出 Flash 应用程序的边界,因此,我希望能够检测到这种情况并重新定位提示。

问题在于组件的高度和宽度显然在被弹出管理器呈现之后才可用。 (即它们总是 0)

但是,我不知道有什么方法可以找出实际呈现弹出窗口的时间以及可用的高度/宽度值。

我尝试向组件添加一个调整大小事件侦听器,但它似乎不起作用,尽管我肯定做错了什么,因为在我看来调整大小事件只给你“oldWidth”和“ oldHeight”,在第一次显示时,它会是 0...对我来说没用。

关于如何进行的任何想法?

-----编辑----- 我有一个这样的基类:

public class TTComponent extends Canvas
{
  var _parentC:UIComponent;
  var popped:Boolean = false;
  var timer:Timer;
  var _comp:UIComponent;

  public function set parentComponent(pC:UIComponent):void 
  {
    _parentC = pc;
    _parentC.addEventListener(MouseEvent.MOUSE_OUT, mouseOut);
    _parentC.addEventListener(MouseEvent.MOUSE_OVER, mouseOver);
  }
  public function mouseOver(evt:MouseEvent):void
  {
    if (_parentC != null)
    {
      timer = new Timer(150,1);
      _comp = this;
      timer.addEventListener(TimerEvent.TIMER_COMPLETE, function( tevt:TimerEvent ):void 
      {
        this.move( somex, somey);
        if (popped != true)
        {
           PopUpManager.addPopUp(_comp, parentComponent );
           popped = true;
        });
        timer.start();
    }
  }

  public function mouseOut(evt:MouseEvent ):void
  {
    if ( timer )
    {
      timer.stop();
      timer = null;
    }
    //If we popped up, remove the popup
    if ( popped )
    {
      PopUpManager.removePopUp( _comp );
      popped = false;
      parentC .removeEventListener(MouseEvent.MOUSE_OUT, mouseOut);
      parentC .removeEventListener(MouseEvent.MOUSE_OVER, mouseOver);
    }
  }
}

然后,像这样的扩展渲染器:

<c:TTComponent name="T" 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:c="components.*">
  <s:BorderContainer>
    ...about 30 labels grouped in various manners
    ...2 lists with inline item renderers
  </s:BorderContainer>
</c:TTComponent>

现在,代码是这样调用的:

var w = new TTComponent();
w.data = data;
win.parentComponent = this;

这将为父级上的鼠标悬停和鼠标移出事件添加侦听器,无论它是什么,然后相应地显示或隐藏工具提示。

-----编辑------

使用下面评论者建议的部分内容,这是我想出的解决方案:

在 TTComponent 类内部:

import flash.events.Event;
import mx.binding.utils.ChangeWatcher;

private var heightWatcher:ChangeWatcher;


public function set parentComponent 
{
  ...
  heightWatcher = ChangeWatcher.watch(this,'height',onSizeChange);
}

public function onSizeChange(evt:Event):void
{
  if (this.height != 0)
  {
    ....calculate the new component coords
    this.move(newx, newy);
  }
}

请注意,此附加代码不会绑定到任何组件变量,它只是在组件属性上添加一个观察器。

【问题讨论】:

  • 我不确定我是否理解。请给代码。

标签: apache-flex actionscript-3 flex4 flash-builder flex4.5


【解决方案1】:

您也可以尝试绑定宽度和高度。如果这些在你的类中是可绑定的,flex 会自动调整你的弹出窗口的宽度和高度。

使用 mxml 进行绑定时,您可以这样做

<mx:YourComponent height="{HeightOfYourTooltip}" width="{WidthOfYourTooltip}"></mx:YourComponent>

如果你想重新定位你的组件,你还可以添加一个监听更改事件的 eventListener,就像这样

<mx:YourComponent height="{HeightOfYourTooltip}" width="{WidthOfYourTooltip}" change="yourComponentResizeHandler()"></mx:YourComponent>

如果您使用的是编程方法,则应该使用 changewatcher。下面展示了如何使用它。

ChangeWatcher.watch(YourComponent, "width", repositionHandler);
ChangeWatcher.watch(YourComponent, "height", repositionHandler);

如果您想观察其他变量或属性的变化,请务必在类中的变量上方添加 [Bindable]-tag,如下所示

[Bindable]
var myVariable:SomeVariable;

我希望这会有所帮助。

【讨论】:

  • 我不确定这种方法是否可行,因为我没有设置组件的高度——它是在运行时确定的。在不知道将其初始化为什么的情况下,如何将变量绑定到高度?
  • 绑定自动更新。如果您提供一些关于如何准确调用组件以及如何构建组件的代码,我可以提供有关如何实现绑定的更多详细信息。
  • 只是给任何阅读者的说明,我对 ChangeWatcher 进行了一些研究,您实际上不必绑定变量来使用它。检查问题中的最新编辑,了解我为解决此问题所做的工作。
  • 您不必绑定组件的高度,因为默认情况下高度是可绑定的。如果您要创建自己的自定义变量,则必须使这些 Bindable :) 很高兴您能够使用 changewatcher 解决问题。
【解决方案2】:

为了显示你在 itemRenderer 中使用了哪些控件的 toolTip?文字还是标签?

【讨论】:

  • 这是一个标签。嗯,实际上,它是一系列标签和 2 个列表。直到运行时我才知道高度的原因是因为插入到列表中的数据。
  • 所以你有 2 个渲染器标签列表。是吗?您要查找 List 或各个标签的高度是谁的身高?
  • 我有一个复杂的渲染器,它包含大约 25 个标签和 2 个未确定大小的列表,它们都放在一个组件内。我正在寻找整个组件的高度。
【解决方案3】:

尝试监听该组件的更新完成事件。愿这能帮助你。 :)

【讨论】:

  • 是个好主意,但没有奏效。在该事件处理程序中高度仍报告为 0。 popupmanager 处理东西的方式一定很奇怪。还有其他想法吗?
【解决方案4】:

这可能很混乱,但是在弹出组件上,您可以在完成触发后添加一个事件侦听器,如果高度或宽度== 0 然后您 setTimeout() 在说 100 毫秒后将其设置为一个函数,直到您获得有效数据.

是的,我知道这有点小技巧,但这些最终会报告正确的测量值,所以它不会调用那么多次。

如果您在截止日期前或类似的情况下只是一个想法并不重要。 :)

【讨论】:

  • 另一个想法是在 init 上创建每种类型中的一种,并且基本上在适当的时候填充和显示,而不是根据需要创建和销毁它们 - 实际上可能是相同的内存,具体取决于类型的数量(因为方式flash 抢占内存,只在需要时收集)它,而且肯定更少 cpu。
  • 实际上,将其中一个驻留在内存中并按需转移数据比每次都从头开始创建数据要快得多。它会根据列表的新大小自动调整大小吗?也许 invalidateSize() 会这样做?
  • 另外,我喜欢你的想法,尽管我试图避免添加黑客。我已经指定了一个“显示”区域,并且每次都在同一位置显示提示,直到我(或我们:D)找到合适的解决方案。
  • 刚刚尝试在内存中保留一个工具提示,可以完美运行并在绑定新数据时自动调整组件大小。好主意!
  • 它实际上是一个更好的解决方案,我自己为出现的工具提示/注释完成了它。很高兴它为你解决了:)
猜你喜欢
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-12
相关资源
最近更新 更多