愚人呓语 eidiot’s blog. My flapdoodles.

2十一/06

AS3笔记-ContextMenu

  写了一个 ContextMenuPlus 类来自定义右键菜单。一行代码可以搞定禁用系统内置菜单(target为设置自定义菜单的目标,如果为自己可以省略):

target.contextMenu = new ContextMenuPlus().contextMenu;

  当然它能做的事情不止于此。看看示例:

  自定义文本区域的右键菜单同样是一行代码:

txt.contextMenu = new ContextMenuPlus(true,
                
onSetTxtColor,
                
"红色文字",
                
"蓝色文字",
                
"黑色文字").contextMenu;


  这里通过构造函数做了三件事情:

  1. 禁用内置菜单
  2. 添加自定义菜单项
  3. 监听menuItemSelect事件
/**
 * @param removeAll            是否禁用所有默认菜单
 * @param listener            自定义菜单事件句柄
 * @param ...customItems    自定义标签,可以是一个数组
 */

public function ContextMenuPlus(removeAll:Boolean = true,
                
listener:Function = null,
                ...
customItems){...}

  就这些了?当然不,看看示例的系统菜单:

var cm:ContextMenuPlus = new ContextMenuPlus(true,
                    
onShowAnswer,
                    
"母亲节是哪天?",
                    
"父亲节是哪天?");
contextMenu = cm.contextMenu;
cm.addCustom(onGetUrl, "eidiot's blog", true);
cm.addGroup(onSetBorderColor,
            
true,
            
"绿色边框",
            
"紫色边框",
            
"黑色边框");

  首先"绑定"自定义菜单到舞台:

var cm:ContextMenuPlus = new ContextMenuPlus(...);
contextMenu = cm.contextMenu;

  然后想怎么玩就怎么玩。先加个链接到我的blog吧:

cm.addCustom(onGetUrl, "eidiot's blog", true);

  这里用到了添加菜单单项的 addCustom 方法:

/**
 * 添加自定义菜单项
 * @param caption            菜单项标题
 * @param listener            事件句柄
 * @param separatorBefore    是否在菜单上方添加分割线
 * @param enabled            是否可用
 * @param visible            是否可见
 */

public function addCustom(listener:Function,
            
caption:String,
            
separatorBefore:Boolean = false,
            
enabled:Boolean = true,
            
visible:Boolean = true):void{...}

  这里要注意一下,原来的 getUrl() 已被 remove ,需要用新的 navigateToURL 方法:

private function onGetUrl(e:ContextMenuEvent):void
{
    
navigateToURL(new URLRequest("http://eidiot.net"),
                    
"_blank");
} 

  再来加个菜单组,改变一下文本边框颜色:

cm.addGroup(onSetBorderColor,
            
true,
            
"绿色边框",
            
"紫色边框",
            
"黑色边框");

  因为他们“同组”,亦即功能统一,只需设置一个事件句柄:

/**
 * 添加自定义菜单组,所有菜单项共用同一个事件句柄
 * 通过 event.currentTarget.caption 区分不同的菜单项
 * private function onSelect(event:ContextMenuEvent):void{
 *         var item:ContextMenuItem = event.currentTarget;
 *         switch(item.caption)...}
 * @param listener            事件句柄
 * @param separatorBefore    是否在菜单组上方添加分隔线
 * @param ...customItems    菜单项标题,可以是一个数组
 */

public function addGroup(listener:Function,
            
separatorBefore:Boolean = false,
            ...
customItems):void{...}

  不想禁用所有的菜单项,还想保留几个?removeDefault可以实现:

/**
 * 禁用默认菜单
 * @param ...leave    保留的菜单项(字符串,逗号隔开)
 */

public function removeDefault(...leave):void{...}

  为了避免在事件里 switch ,我在 测试代码 里使用对象来对应选项:

//设置对照列表
private function initObj():void
{
    
txtColorObj["红色文字"] = 0xFF0000;
    
txtColorObj["蓝色文字"] = 0x0000FF;
    
txtColorObj["黑色文字"] = 0x000000;
}
//读取列表值
private function onSetTxtColor(e:ContextMenuEvent):void
{
    
txt.textColor = txtColorObj[e.currentTarget.caption];
}

  具体的实现就不罗唆了,看看 测试代码类代码

相关日志

  • 初學者
    這帖真的挺有趣的
    受益了
  • yuxuan2658
    汗,你真的牛人,学习了,我将你的博客发现的迟了
  • Anonymous
    好,我是一个初学者!
  • 这个是我代码里的问题,不知道当初为什么可以通过编译检查,改成 txt = getChildByName(”testTxt”) as TextField; 就可以了
  • mhmnz2
    为什么我自己新建个fla来测试,会有以下错误

    1118: 属于 static 类型 flash.display:DisplayObject 的值的隐式强制指令的目标可能是非相关类型 flash.text:TextField。

    代码指向的错误行是下面这句:
    txt = getChildByName("testTxt");
  • sunshine008
    厉害,以前还不知as可以有右键菜单呢
  • 不错啊~ 呵呵
    确实比我早了一年整
    厉害~~
    不过我以前从来没弄过自定义菜单
    我把它认为是边缘技术
    as3也是刚弄不久
    还菜的很
    多指教
  • Kevin
    不错。。
blog comments powered by Disqus