Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex 有没有办法监听弹出式管理器类上的事件?_Apache Flex_Flex4 - Fatal编程技术网

Apache flex 有没有办法监听弹出式管理器类上的事件?

Apache flex 有没有办法监听弹出式管理器类上的事件?,apache-flex,flex4,Apache Flex,Flex4,我试图检测弹出窗口何时可见(如果可能,包括工具提示)。原因是当弹出窗口出现时,我需要隐藏或冻结(捕获快照)Stage*组件(StageWebView、StageVideo、StageText等) 要做到这一点,没有真正简单的方法。你能做的是: 创建自定义popupmanager 使其在应用程序上分派事件,以便您可以在任何地方侦听 告诉Flex使用您的类而不是默认实现 创建自定义PopupManager 我们创建了一个自定义的PopupManager类,可以向其中添加一些自定义功能。例如,在您

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

要做到这一点,没有真正简单的方法。你能做的是:

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

我们创建了一个自定义的PopupManager类,可以向其中添加一些自定义功能。例如,在您的情况下,在应用程序上调度一个事件可能会很有趣,这样我们就可以从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已经注册了一个实现,即使在“预初始化”时执行,也无法覆盖它。所以我们必须在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" >
额外信息

现在为什么MyPopupManager必须有一个静态getInstance()方法?这是因为我们用来注册实现的Singleton类期望它注册的每个类都是Singleton,因此有一个名为“getInstance”的方法。它将尝试调用此方法,如果该方法不存在,它将崩溃。如果你不知道什么是单身汉,就用谷歌搜索吧。你会发现大量的信息


PS:为了解决这个问题,我实际上学到了一些新的东西(谢谢你)。

对于我的
Spark
应用程序,我不得不对RIAStar的答案做一些其他修改。在
预加载程序.initialize()
中还没有找到我的自定义类(
ApplicationDomain.currentDomain.getDefinition()
),因此我为
预加载程序\u DOC\u FRAME\u 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相同

谢谢。我很高兴能帮你学点新东西你是对的。此方法是实现此功能的方法,但它超出了此功能的范围。如何侦听systemManager addChild或AddedStatage事件?systemManager numOfElements或numOfChildren是否可绑定?我可以将可见性绑定到systemManager.NumoElement在您的学习中,您知道Singleton.registerClass是否适用于任何类吗?我能把它用于我自己的邪恶目的吗?还有一条评论要补充。开放声明不适用于PopUpManager,因为它指向实现,所以这很好,您已经找到了此信息。@1.21gigawatts Q1:我不这么认为。我想不出一种方式,你会知道,任何对象被添加到显示列表中,实际上是作为弹出窗口添加的。问题2:是的,你可以。它本质上只是一个接口及其单例实现的字典。只需通过调用
Singleton.getInstance(“path.to::MyInterface”)
来获取已注册的实现。只需确保实现有一个
getInstance()
方法。事实上,您是对的。
PopUpManagerImpl#addPopUp()
方法将弹出窗口的
isPopUp
属性设置为
true
(SDK 4.6版本中的第334行)。因此,这种方法可能会奏效。
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);
            }
        }
    }
}