【问题标题】:flex button event listeners in ClassClass 中的 flex 按钮事件监听器
【发布时间】:2009-08-04 13:13:38
【问题描述】:

我在 Main.mxml 中有很多按钮。我正在尝试将按钮功能移动到一个类中,并让类内的事件侦听器响应 Click 并调用其他函数。我写过:

Main.mxml

<mx:Button x="23.5" y="10" label="checker" click="{goListen()}" />
<mx:Button id="btnT1" x="252.5" y="10" label="t1" />
<mx:Button id="btnT2" x="309" y="10" label="t2"/>
<mx:Button id="btnT3" x="366" y="10" label="t3"/>

Main.as

private function goListen():void
    {
        var t:ButtonListener = new ButtonListener(btnT1, btnT2, btnT3);
    }

ButtonListener.mxml

package com.util

{ 导入 flash.events.EventDispatcher; 导入 flash.events.MouseEvent;

import mx.controls.Alert;
import mx.controls.Button;

public final class ButtonListener extends EventDispatcher
{
    private var __btnArray:Array;

    public function ButtonListener(...btnList)
    {
        __btnArray = new Array();

        for each (var item:Button in btnList)
        {
            __btnArray.push(item);
        }

        buildListeners();
    }

    private function buildListeners():void
    {
        for each (var item:Button in __btnArray)
        {
            item.addEventListener(MouseEvent.CLICK, traceMe, false, 0, true);
        }
    }

    private function traceMe(event:MouseEvent):void
    {
        trace(event.target.label + " was clicked");
    }
}

}

所以当我调试时,我看到数组填满了按钮,但是 traceMe() 函数不起作用。不知道我怎样才能让它工作。还是我只需要在主类中有 30 个事件侦听器和相应的函数。

【问题讨论】:

    标签: apache-flex class button event-handling flexbuilder


    【解决方案1】:

    看起来您有两个不同的选择或问题。如果更改最后一个参数:

    item.addEventListener(MouseEvent.CLICK, traceMe, false, 0, true);
    

    false,那么一切都会正常工作,因为您的事件侦听器会一直处理鼠标点击。当然,这意味着如果您再次单击“检查器”按钮,那么您将有两组侦听器响应鼠标单击按钮一、二和三。

    因此,您感兴趣的真正解决方案可能是保持上面引用的行不变,而是更改以下行:

    var t:ButtonListener = new ButtonListener(btnT1, btnT2, btnT3);
    

    如果您更改上述行以将按钮侦听器存储为类的一部分,它将可以响应鼠标点击,而不是被垃圾收集:

    _buttonListener = new ButtonListener(btnT1, btnT2, btnT3);
    

    当然,假设您在 mx:script 块中定义了_buttonListener

    <mx:Script><![CDATA[
        var _buttonListener:ButtonListener;
     ]]></mx:Script>
    

    编辑每条评论:

    在提供的代码中,tButtonListener 超出了范围。当它发生时,除非您使用强引用,否则它会被垃圾收集,您不会根据 addEventListener 调用中的最后一个参数。

    因此,让按钮监听器成为主类的成员:

    Main.mxml 将显示为:

    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
        <mx:Button x="23.5" y="10" label="checker" click="{goListen()}" />
        <mx:Button id="btnT1" x="252.5" y="10" label="t1" />
        <mx:Button id="btnT2" x="309" y="10" label="t2"/>
        <mx:Button id="btnT3" x="366" y="10" label="t3"/>
        <mx:Script>
            <![CDATA[
                private var _buttonListener:ButtonListener;
    
                private function goListen():void
                {                
                    _buttonListener = new ButtonListener(btnT1, btnT2, btnT3); 
                }
            ]]>
        </mx:Script>
    </mx:Application>
    

    由于事件监听器将不再超出范围,事件监听器使用的弱引用将按预期工作,当__buttonListener 超出范围时被垃圾回收。

    【讨论】:

    • Kaleb,您发布的第一个解决方案有效,因为我使用检查器按钮作为测试来实例化 ButtonListener 类。但是,当应用程序加载时,我将实例化它。无论如何,我都无法收集事件侦听器的垃圾,因为我需要所有按钮在整个电影中播放。但是,我不明白你的第二个解决方案。你能详细说明一下吗?
    【解决方案2】:

    由于 Button 的 click 事件会冒泡,因此您可以只在主应用程序文件上侦听 click 事件并委托给类中的处理函数。

    或者您可以在单击按钮时直接调用处理程序。

    private var controller:ButtonListener = new ButtonListener();
    
    <mx:Button id="btnT1" x="252.5" y="10" label="t1" click="controller.handleClick(event)"/>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 2014-08-04
      • 2014-04-11
      • 1970-01-01
      • 2012-10-10
      相关资源
      最近更新 更多