高度变化AS3的自定义事件

时间:2022-11-03 00:05:01

how can i add an event listener to detect when the height of a DisplayObject changes.

如何添加事件侦听器以检测DisplayObject的高度何时更改。

i have a holding Sprite with a border that needs to resize when any object inside changes height or is added.

我有一个带有边框的Sprite,当内部任何对象改变高度或添加时,需要调整大小。

thanks.

Josh

4 个解决方案

#1


i presume this is a flash and not a Flex question ... which is why mx.events.ResizeEvent (which is dispatched by UIComponent and subclasses) and all this kind of funky Flex stuff won't work ... if you do use Flex and UIComponents, it's the best way to go though ...

我认为这是一个闪存,而不是一个Flex问题...这就是为什么mx.events.ResizeEvent(由UIComponent和子类调度)和所有这种时髦的Flex东西将无法工作...如果你使用Flex和UIComponents,这是最好的方式...

the problem is, that this event is not generated ...

问题是,这个事件没有生成......

  • you could subclass any builtin classes, override the accessors for width, height, x, y, scaleX, scaleY, transform and visible, to get most information ...
  • 你可以子类化任何内置类,覆盖宽度,高度,x,y,scaleX,scaleY,transform和visible的访问器,以获取大多数信息......

  • you would have to make sure, that any object is an instance of your custom classes ... you would not be able to use startDrag, since it bypasses the accessors ...
  • 您必须确保,任何对象都是您的自定义类的实例...您将无法使用startDrag,因为它绕过了访问者...

  • you really got practically NO chance to find out, if someone draws on a subobject ... Graphics is final ... except, overriding the getter and setting a timeout, when the getter is used, to check changes 1 msec later (and be sure you have 1 timeout at max) ...
  • 你真的几乎没有机会找到,如果有人在子对象上画画...图形是最终的...除了,当使用getter时覆盖getter并设置超时,以便在1毫秒之后检查更改(并且是确保你最多有1次超时)...

this is more than dodgy, takes a lot of developement and debugging time, will be a pain in the ass, since you will have to make absolutely sure, everything (also any library symbol, if you use CS3/CS4 as i presume) ... and will eat up quite a chunk of performance due to all the events dispatched by your custom accessors ...

这不仅是狡猾,需要大量的开发和调试时间,将是一个痛苦的屁股,因为你必须绝对肯定,一切(也任何库符号,如果你使用CS3 / CS4,我猜)。 ..由于您的自定义访问者发送的所有事件,将占用相当大的性能...

the most simple thing really, is to watch the width/height on enterframe and if they change from one frame to another, then redraw your border ... this makes much more sense, since you don't need to redraw the border more then once a frame, which is an effect that could very well occur, if you tried to capture any actions that could possibly mean resizing ... and really, comparing two floats is very cheap ... :)

真正最简单的事情是观察enterframe的宽度/高度,如果它们从一帧变为另一帧,那么重绘你的边框......这更有意义,因为你不需要再重绘边框了一旦一帧,这是一种很可能发生的效果,如果你试图捕捉任何可能意味着调整大小的动作......而且真的,比较两个花车非常便宜...... :)

hope that helped ...

希望有帮助......

greetz

back2dos

#2


displayObject.addEventListener(ResizeEvent.RESIZE, onResize);

function onResize(event:ResizeEvent):void
{
    // handle it here
}

#3


Create the custom event class:

创建自定义事件类:

package com
{
    class ChildResizeEvent extends Event
    {
        public static var RESIZE:String = "resize";
        public static var ADDED:String = "added";
    }
}

In main Sprite MXML you can use this:

在主Sprite MXML中,您可以使用:

<mx:Metadata>
    [Event(name="onChildResize", type="com.ChildResizeEvent")]
</mx:Metadata>

Then when the event happens (When an object changes height or is added), you dispatch:

然后当事件发生时(当一个对象改变高度或被添加时),你发送:

function onInteriorObjectHeightChange(event:Event):void
{
    dispatchEvent(new ChildResizeEvent(ChildResizeEvent.RESIZE));
}

#4


Thoughts

At first I was surprised the implementation of the DisplayObject class does not dispatch Event.RESIZE events when its width and height properties are changed or the size of the contents is recalculated, but it makes a lot of sense for performance reasons.

起初,我很惊讶DisplayObject类的实现在调整其宽度和高度属性或重新计算内容的大小时不调度Event.RESIZE事件,但出于性能原因,这很有意义。

I thought about using the Event.RENDER event, but I was listening for it on a TextField that I was resizing like crazy through a script... and despite the text re-wrapping, and the box expanding and the cursor flashing... it NEVER fired a single RENDER event. Surprising, it only fires the RENDER event when the text is changed, which just shows how useless the RENDER event is.

我想过使用Event.RENDER事件,但我正在TextField上监听它,我正在通过脚本疯狂地调整大小...尽管文本重新包装,框展开,光标闪烁......它永远不会发射一个RENDER事件。令人惊讶的是,它只会在文本发生变化时触发RENDER事件,这只会显示RENDER事件是多么无用。

Answer... focus on the circumstances or frequency with which you expect the DisplayObject to change size.

I suggest that you either:

我建议你要么:

  1. Dispatch Event.RESIZE events from any custom subclass of DisplayObject that you create. OR
  2. 从您创建的DisplayObject的任何自定义子类中调度Event.RESIZE事件。要么

  3. Use the Event.ENTER_FRAME event to monitor the width and height of any DisplayObject you expect to change dimensions.
  4. 使用Event.ENTER_FRAME事件来监视您希望更改尺寸的任何DisplayObject的宽度和高度。

Logically, the method you choose should depend on what you know about the DisplayObject's likelihood to change size:

从逻辑上讲,您选择的方法应取决于您对DisplayObject更改大小的可能性的了解:

  • If you expect it to change size unexpectedly (e.g. like a dynamic particle system)... then it makes sense to monitor its unpredictable dimensions with ENTER_FRAME, especially if you're certain it's dimensions are likely to change every frame.
  • 如果您希望它意外地改变大小(例如像动态粒子系统)......那么使用ENTER_FRAME监视其不可预测的尺寸是有意义的,特别是如果您确定它的尺寸可能每帧都会改变。

  • Alternatively, if you know the object will resize only under particular conditions (e.g. during a TextField's Event.CHANGE event) or it's a class you created yourself... then YOU should know whether what you're doing might cause the size to change, and simply dispatch an Event.RESIZE event from your class.
  • 或者,如果您知道对象仅在特定条件下调整大小(例如在TextField的Event.CHANGE事件期间)或者您自己创建的类...那么您应该知道您正在做的事情是否会导致大小改变,并简单地从您的班级调度Event.RESIZE事件。

#1


i presume this is a flash and not a Flex question ... which is why mx.events.ResizeEvent (which is dispatched by UIComponent and subclasses) and all this kind of funky Flex stuff won't work ... if you do use Flex and UIComponents, it's the best way to go though ...

我认为这是一个闪存,而不是一个Flex问题...这就是为什么mx.events.ResizeEvent(由UIComponent和子类调度)和所有这种时髦的Flex东西将无法工作...如果你使用Flex和UIComponents,这是最好的方式...

the problem is, that this event is not generated ...

问题是,这个事件没有生成......

  • you could subclass any builtin classes, override the accessors for width, height, x, y, scaleX, scaleY, transform and visible, to get most information ...
  • 你可以子类化任何内置类,覆盖宽度,高度,x,y,scaleX,scaleY,transform和visible的访问器,以获取大多数信息......

  • you would have to make sure, that any object is an instance of your custom classes ... you would not be able to use startDrag, since it bypasses the accessors ...
  • 您必须确保,任何对象都是您的自定义类的实例...您将无法使用startDrag,因为它绕过了访问者...

  • you really got practically NO chance to find out, if someone draws on a subobject ... Graphics is final ... except, overriding the getter and setting a timeout, when the getter is used, to check changes 1 msec later (and be sure you have 1 timeout at max) ...
  • 你真的几乎没有机会找到,如果有人在子对象上画画...图形是最终的...除了,当使用getter时覆盖getter并设置超时,以便在1毫秒之后检查更改(并且是确保你最多有1次超时)...

this is more than dodgy, takes a lot of developement and debugging time, will be a pain in the ass, since you will have to make absolutely sure, everything (also any library symbol, if you use CS3/CS4 as i presume) ... and will eat up quite a chunk of performance due to all the events dispatched by your custom accessors ...

这不仅是狡猾,需要大量的开发和调试时间,将是一个痛苦的屁股,因为你必须绝对肯定,一切(也任何库符号,如果你使用CS3 / CS4,我猜)。 ..由于您的自定义访问者发送的所有事件,将占用相当大的性能...

the most simple thing really, is to watch the width/height on enterframe and if they change from one frame to another, then redraw your border ... this makes much more sense, since you don't need to redraw the border more then once a frame, which is an effect that could very well occur, if you tried to capture any actions that could possibly mean resizing ... and really, comparing two floats is very cheap ... :)

真正最简单的事情是观察enterframe的宽度/高度,如果它们从一帧变为另一帧,那么重绘你的边框......这更有意义,因为你不需要再重绘边框了一旦一帧,这是一种很可能发生的效果,如果你试图捕捉任何可能意味着调整大小的动作......而且真的,比较两个花车非常便宜...... :)

hope that helped ...

希望有帮助......

greetz

back2dos

#2


displayObject.addEventListener(ResizeEvent.RESIZE, onResize);

function onResize(event:ResizeEvent):void
{
    // handle it here
}

#3


Create the custom event class:

创建自定义事件类:

package com
{
    class ChildResizeEvent extends Event
    {
        public static var RESIZE:String = "resize";
        public static var ADDED:String = "added";
    }
}

In main Sprite MXML you can use this:

在主Sprite MXML中,您可以使用:

<mx:Metadata>
    [Event(name="onChildResize", type="com.ChildResizeEvent")]
</mx:Metadata>

Then when the event happens (When an object changes height or is added), you dispatch:

然后当事件发生时(当一个对象改变高度或被添加时),你发送:

function onInteriorObjectHeightChange(event:Event):void
{
    dispatchEvent(new ChildResizeEvent(ChildResizeEvent.RESIZE));
}

#4


Thoughts

At first I was surprised the implementation of the DisplayObject class does not dispatch Event.RESIZE events when its width and height properties are changed or the size of the contents is recalculated, but it makes a lot of sense for performance reasons.

起初,我很惊讶DisplayObject类的实现在调整其宽度和高度属性或重新计算内容的大小时不调度Event.RESIZE事件,但出于性能原因,这很有意义。

I thought about using the Event.RENDER event, but I was listening for it on a TextField that I was resizing like crazy through a script... and despite the text re-wrapping, and the box expanding and the cursor flashing... it NEVER fired a single RENDER event. Surprising, it only fires the RENDER event when the text is changed, which just shows how useless the RENDER event is.

我想过使用Event.RENDER事件,但我正在TextField上监听它,我正在通过脚本疯狂地调整大小...尽管文本重新包装,框展开,光标闪烁......它永远不会发射一个RENDER事件。令人惊讶的是,它只会在文本发生变化时触发RENDER事件,这只会显示RENDER事件是多么无用。

Answer... focus on the circumstances or frequency with which you expect the DisplayObject to change size.

I suggest that you either:

我建议你要么:

  1. Dispatch Event.RESIZE events from any custom subclass of DisplayObject that you create. OR
  2. 从您创建的DisplayObject的任何自定义子类中调度Event.RESIZE事件。要么

  3. Use the Event.ENTER_FRAME event to monitor the width and height of any DisplayObject you expect to change dimensions.
  4. 使用Event.ENTER_FRAME事件来监视您希望更改尺寸的任何DisplayObject的宽度和高度。

Logically, the method you choose should depend on what you know about the DisplayObject's likelihood to change size:

从逻辑上讲,您选择的方法应取决于您对DisplayObject更改大小的可能性的了解:

  • If you expect it to change size unexpectedly (e.g. like a dynamic particle system)... then it makes sense to monitor its unpredictable dimensions with ENTER_FRAME, especially if you're certain it's dimensions are likely to change every frame.
  • 如果您希望它意外地改变大小(例如像动态粒子系统)......那么使用ENTER_FRAME监视其不可预测的尺寸是有意义的,特别是如果您确定它的尺寸可能每帧都会改变。

  • Alternatively, if you know the object will resize only under particular conditions (e.g. during a TextField's Event.CHANGE event) or it's a class you created yourself... then YOU should know whether what you're doing might cause the size to change, and simply dispatch an Event.RESIZE event from your class.
  • 或者,如果您知道对象仅在特定条件下调整大小(例如在TextField的Event.CHANGE事件期间)或者您自己创建的类...那么您应该知道您正在做的事情是否会导致大小改变,并简单地从您的班级调度Event.RESIZE事件。