Flex弹出菜单与工具提示重叠

最近项目中遇到一个问题:按钮的工具提示与弹出菜单重叠。原来工具提示由ToolTipManager管理,而弹出菜单由PopUpManager管理,它们的层次都是由SystemManager管理。默认情况下,工具提示层会比弹出菜单层高,这就会导致工具提示总在弹出菜单的上面。可使用PopUpManager的bringToFront方法来交换弹出菜单与工具提示的层次从而避免重叠。看下面代码:

<?xml version="1.0" encoding="utf-8"?>
<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">
  
  <fx:Script>
    <![CDATA[
      import mx.controls.Alert;
      import mx.controls.Menu;
      import mx.events.MenuEvent;
      import mx.managers.PopUpManager;
      private var _menu:Menu = new Menu();
      
      private function showMenu(event:MouseEvent):void {
        PopUpManager.removePopUp(_menu);
        _menu = Menu.createMenu(null, xml, false);
        _menu.labelField = "@label";
        _menu.addEventListener(MenuEvent.ITEM_CLICK, menuHandler);
        _menu.show(btn.x, btn.y + 25);
        PopUpManager.bringToFront(_menu);
      }
      private function menuHandler(evt:MenuEvent):void  {
        Alert.show("Label: " + evt.item.@label, "Clicked menu item");
      }
      
      protected function btn_rollOverHandler(event:MouseEvent):void
      {
        PopUpManager.removePopUp(_menu);    
      }
      
    ]]>
  </fx:Script>
  
  <fx:Declarations>
    <fx:XML id="xml">
      <root>
        <menuitem label="copy" eventName="copy"/>
        <menuitem label="paste" eventName="paste"/>
      </root>
    </fx:XML>
  </fx:Declarations>
  
  <s:Button id="btn" x="50" y="50" 
    toolTip="This is a ToolTip" label="Open Menu" 
    click="showMenu(event);" rollOver="btn_rollOverHandler(event)"/>
  
</s:Application>

另个一种解决办法就是设置一个标识变量,然后通过菜单的事件侦听器改变这个变量来决定是否显示工具提示。

看下面代码:

<?xml version="1.0" encoding="utf-8"?>
<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">

  <fx:Script>
    <![CDATA[
      import mx.controls.Alert;
      import mx.controls.Menu;
      import mx.events.MenuEvent;
      private var _menu:Menu;

      [Bindable]
      private var showToolTip:Boolean = true;

      private function showMenu(event:MouseEvent):void {
        _menu = Menu.createMenu(null, xml, false);
        _menu.labelField = "@label";
        _menu.addEventListener(MenuEvent.ITEM_CLICK, menuHandler);
        _menu.addEventListener(MenuEvent.MENU_SHOW, function():void{
          showToolTip = false;
        });
        _menu.addEventListener(MenuEvent.MENU_HIDE, function():void{
          showToolTip = true;
        });
        _menu.show(btn.x, btn.y + 25);
      }
      private function menuHandler(evt:MenuEvent):void  {
        Alert.show("Label: " + evt.item.@label, "Clicked menu item");
      }

    ]]>
  </fx:Script>

  <fx:Declarations>
    <fx:XML id="xml">
      <root>
        <menuitem label="copy" eventName="copy"/>
        <menuitem label="paste" eventName="paste"/>
      </root>
    </fx:XML>
  </fx:Declarations>

  <s:Button id="btn" x="50" y="50" 
    toolTip="{showToolTip ? 'This is a ToolTip' : ''}" 
    label="Open Menu" click="showMenu(event);"/>

</s:Application>

显然,前一种方法要简单一些。

发表评论