我正在尝试检测弹出窗口何时可见(如果可能,包括工具提示)。原因是我需要在出现弹出窗口时隐藏或冻结(捕获快照)Stage *组件(StageWebView,StageVideo,StageText等)。
答案 0 :(得分:2)
实现这一目标并不是一件容易的事。你能做的是:
创建自定义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语句:
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类,期望它注册的每个类都是一个单例,因此有一个名为'getInstance'的方法。它将尝试调用此方法,如果它不存在将崩溃。如果你不知道单身是什么,只需谷歌。你会发现很多信息。
PS:我实际上已经学会了一些新的尝试来解决这个问题(谢谢你)。答案 1 :(得分:0)
对于我的Spark
Application
,我必须对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相同。