apache-flex 是否有方法侦听弹出窗口管理器类上的事件?

lymgl2op  于 2022-11-01  发布在  Apache
关注(0)|答案(2)|浏览(140)

我正在尝试检测弹出窗口何时可见(如果可能,包括工具提示)。原因是,我需要在弹出窗口出现时隐藏或冻结(捕获快照)Stage* 组件(StageWebView、StageVideo、StageText等)。

cygmwpex

cygmwpex1#

要做到这一点并不容易。你可以这样做:

  • 创建自定义弹出窗口管理器
  • 使其在应用程序上分派事件,以便您可以在任何地方侦听
  • 告诉Flex使用您的类而不是默认实现
    创建自定义PopupManager

我们创建了一个自定义的PopupManager类,我们可以在其中添加一些自定义功能。例如,在您的情况下,在Application上调度一个事件可能会很有趣,这样我们就可以从displayList上的任何地方侦听它。我们将扩展PopUpManagerImpl,这是Flex使用的默认实现。

public class MyPopupManager extends PopUpManagerImpl {

    private static var instance:IPopUpManager;

    static public function getInstance():IPopUpManager 
    {
        if (!instance) instance = new MyPopupManager();
        return instance;
    }

    override public function addPopUp(
        window:IFlexDisplayObject, 
        parent:DisplayObject, 
        modal:Boolean=false, 
        childList:String=null, 
        moduleFactory:IFlexModuleFactory=null):void 
    {
        super.addPopUp(window, parent, modal, childList, moduleFactory);
        var app:IEventDispatcher = 
            IEventDispatcher(FlexGlobals.topLevelApplication);
        app.dispatchEvent(new Event("popupAdded", true));
    }

}

我们重写addPopup方法以在弹出窗口显示时调度冒泡事件。现在忽略getInstance()方法。稍后我将返回到该方法。您需要知道的是,FlashBuilder不会自动管理您的一些导入,因为这些类被标记为隐藏。无需担心,但您必须为以下内容手动编写导入语句:

import mx.managers.IPopUpManager;
import mx.managers.PopUpManagerImpl;

告诉Flex使用您的类而不是默认实现

这将是相当容易的:

import mx.core.Singleton;
Singleton.registerClass("mx.managers::IPopUpManager", MyPopupManager);

唯一的问题是Flex已经注册了一个实现,你不能覆盖它,即使你在'preinitialize'上执行它。所以我们必须在Flex开始引导之前完成它。我们将使用一个自定义的预加载器:

public class RegisteringPreloader extends DownloadProgressBar {

    override public function initialize():void {
        super.initialize();
        Singleton.registerClass("mx.managers::IPopUpManager", MyPopupManager);
    }

}

DownloadProgressBar是默认的Flex预加载器。我们只是添加了额外的注册代码。现在,不要忘记告诉您的应用程序使用此预加载器:

<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"
               preloader="RegisteringPreloader" >

"现在就听这件事"

addEventListener("popupAdded", onPopupAdded);
PopUpManager.addPopUp(new Panel(), this);

额外信息

现在为什么MyPopupManager必须有一个静态的getInstance()方法呢?这是因为我们用来注册实现的Singleton类,期望它注册的每个类都是一个singleton,因此有一个名为'getInstance'的方法。它会尝试调用这个方法,如果它不存在,就会崩溃。如果你不知道什么是singleton,只要谷歌一下。你会找到大量的信息。
PS:我实际上学到了一些新的东西,试图解决这个问题(谢谢)。

vwkv1x7d

vwkv1x7d2#

对于我的SparkApplication,我不得不对RIAStar的答案做一些其他的修改。我的自定义类还没有在preloader.initialize()ApplicationDomain.currentDomain.getDefinition())中找到,所以我为PRELOADER_DOC_FRAME_READY事件添加了一个事件侦听器。

package com.mydomain.preloaders {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.system.ApplicationDomain;
    import flash.utils.getDefinitionByName;

    import mx.core.Singleton;
    import mx.events.FlexEvent;
    import mx.preloaders.SparkDownloadProgressBar;

    public class RegisteringPreloader extends SparkDownloadProgressBar {

        public function RegisteringPreloader() {

        }

        public var preloaderSprite:Sprite;

        override public function set preloader(value:Sprite):void {
            super.preloader = value;

            preloaderSprite = value;

            value.addEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY, preloaderCompleteHandler);

        }

        protected function preloaderCompleteHandler(event:Event):void {
            var myCustomClass:Class;
            var classPath:String;
            var hasDefinition:Boolean;

            preloaderSprite.addEventListener(FlexEvent.PRELOADER_DOC_FRAME_READY, preloaderCompleteHandler);

            classPath = "com.domain.managers::MyClassImpl";
            hasDefinition = ApplicationDomain.currentDomain.hasDefinition(classPath);

            if (hasDefinition) {
                myCustomClass = Class(getDefinitionByName(classPath));

                Singleton.registerClass("mx.managers::ISingletonClass", myCustomClass);
            }
        }
    }
}

其余步骤与RIAStar相同。

相关问题