【问题标题】:Modal window in FlashFlash 中的模态窗口
【发布时间】:2009-07-09 17:24:34
【问题描述】:

短版:

在 Flash (AS3) 中编程模态窗口是否容易/可行/可能?它有内置功能吗?

加长版:

我正在开发一个 Flash 小部件(在 AS3 中),我希望能够以模态方式显示影片剪辑。从本质上讲,我需要在 wieget 内有一个简单的模态窗口。到目前为止,我了解到我需要自己实现“模态”(在 AS3 中)。以前版本的 Flash 中有一些东西,Flex 中也有一些东西,但我没有使用 Flax 的经验,我不确定它涉及到什么。

我开始自己编写它,没有任何深入的计划,很快就遇到了一些问题。似乎问题的根源在于我无法将注意力集中在电影剪辑上(或者准确地说是InteractiveObject)。我同时处理KEY_FOCUS_CHANGEMOUSE_FOCUS_CHANGE 事件,同时试图防止失去焦点FocusEvent.preventDefault()。但我仍然设法通过鼠标点击失去焦点。更奇怪的是,当我使用Stage.focus 属性强制聚焦时,我的影片剪辑周围出现了一条难看的粗黄线。 In 大概表示影片剪辑已聚焦,但通常它不在任何地方。这是否意味着该对象不可聚焦,但我还是以某种方式强制聚焦它?

我意识到上面的问题不是很清楚,我不希望真正回答它们。但我想表明的是,我似乎做错了什么。所以主要的问题是:有没有一种简单的方法可以在 Flash 中获得模态行为?我认为从头开始编程、管道和处理各种小事件是我不应该做的事情。

最让我恼火的是我需要这个模态寡妇来处理和显示一些极端情况的错误消息。所以投入这么多精力似乎是不对的。也许,有一种完全不同的方式。

我知道这个问题可能没有足够的研究支持这一事实,但我开始研究一些我认为需要半小时的东西,而现在已经花了几个小时。以后我可能会做更系统的研究并发布更具体的问题。

【问题讨论】:

    标签: flash actionscript-3


    【解决方案1】:

    经过更多的实验和调查,我想我找到了一个相当干净的解决方案。大部分是基于FocusEvent event的官方文档中的示例。以下是植入的简化版本。

    package
    {
    
        import flash.events.Event;
        import flash.events.MouseEvent;
        import flash.events.FocusEvent;
        import flash.display.Sprite;
        import flash.display.Stage;
    
        public class Message
        {
    
            private static var overlay : Sprite;
            private static var dialog : Sprite;
    
            public static function show(stage : Stage, message : String)
            {
    
                // Close existing (if any).
                close();
    
                // Create dialog. They overlay sprite overlays the entire scene.
                overlay = createOverlay();
                dialog = createDialog(message);
                overlay.addChild(dialog);
                stage.addChild(overlay);
    
                // steal focus
                stage.focus = overlay;
    
                // Make sure the ugly yellow focus rectangle is hidden. Hiding it seems
                // to have one additional benefit. If we don’t do it, one can still 
                // change the focus using left and right arrow keys. The focus rectangle
                // actually moves to another element in the scene (first time I saw
                // something like this in Flash). If we hide it, the left and right arrow
                // keys actually don’t do anything. I did not find any documentation
                // related to this. So it may change in future. But if it changes,
                // possible workaround could be to simply catch the keyboard events
                // and prevent propagation. Such approach is also used in the official
                // AS3 documentation of the FocusEvent class:
                // 
                //   http://livedocs.adobe.com/
                //       flash/9.0/ActionScriptLangRefV3/flash/events/FocusEvent.html
                //
                stage.stageFocusRect = false;
    
                // Even though the message overlays the entire stage, if you click
                // on it, it loses focus. My guess is that Flash does not find
                // anything obvious which can be focused (such as a textbox). The
                // following below forces Flash to keep the focus on the message.
                // This approach is also used in an example in the AS3 documentation,
                // of the of the FocusEvent class (see the link above) so it gives it
                // some credibility.
                overlay.addEventListener(MouseEvent.CLICK,
                    function(event : MouseEvent) : void { stage.focus = overlay; });
    
                // In addition, when the entire Flash loses focus and it gets it later 
                // back, the container (browser) does not restore the previously focused
                // element. So we have to do it ourselves.
                stage.addEventListener(Event.ACTIVATE,
                    function(event : Event) : void { stage.focus = overlay; });
    
                // And apparently, swallow all keyboard events.
                overlay.addEventListener(KeyboardEvent.KEY_DOWN,
                    function(event : KeyboardEvent) : void { event.stopPropagation(); });
    
            }
    
            public static function close() : void
            {
                // snip ...
            }
    
            private static function createOverlay() : Sprite
            {
                // snip ...
            }
    
            private static function createDialog(message : String) : Sprite
            {
                // snip ...
            }
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      很简单: 您只需添加一个覆盖整个 Flash 的矩形,然后在其顶部添加模态窗口。所有鼠标事件都将被这个矩形捕获。如果需要,您可以将焦点设置为 null,确保也没有键盘事件。 下面的代码是这个矩形的一个类。在模态窗口之前使用 addChild() 添加它。

      import flash.display.Graphics;
      import flash.display.Sprite;
      import flash.events.Event;
      
      public class ModalCoverSprite extends Sprite
      {
          public function ModalCoverSprite()
          {
              super();
              graphics.beginFill( 0, 0.3 ); //alpha can be 0 as well.
              graphics.drawRect( 0, 0, 100, 100 );
              graphics.endFill( );
              addEventListener(Event.ADDED_TO_STAGE, onAdded);
      
          }
      
          private function fitToBrowser():void 
          {
              width=stage.stageWidth;
              height=stage.stageHeight;
          }
      
          private function onBrowserResize(event:Event):void
          {
              fitToBrowser();
          }
      
          private function onAdded(event:Event):void 
          {
              fitToBrowser();
              stage.addEventListener( ExternalBrowserEvent.RESIZE, onBrowserResize );
              addEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
          }
      
          protected function onRemoved(event:Event):void
          {
              stage.removeEventListener( ExternalBrowserEvent.RESIZE, onBrowserResize );
              removeEventListener(Event.REMOVED_FROM_STAGE, onRemoved);
          }
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2017-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-22
        • 1970-01-01
        相关资源
        最近更新 更多