Android开发指南-用户界面-创建菜单

系统 2152 0

创建菜单 Creating Menus

菜单是任何应用程序的一个重要部分,提供了透露应用程序功能和设置的通用接口。 Android 为开发者提供了一个简单的编程接口来实现各种条件下的标准化应用程序菜单。

Android 提供了三种基础菜单类型:

选项菜单 Options Menu

这是一个活动的主菜单。通过按下设备菜单键来显示它。选项菜单包含两组菜单项:

图标菜单 Icon Menu

这个是当用户按下菜单键时最初出现屏幕下方的 item 集合。它支持最多 6 个菜单项。只有这些菜单支持图标而且这些菜单并不支持 checkboxes 或者 radio buttons

扩展菜单 Expanded Menu

这是通过按“更多”菜单显现出来的一个竖向的项目列表。它仅当图标菜单过多时存在而且是由 6 个以及其它选项菜单组成。

上下文菜单 Context Menu

这是一个浮动菜单列表,通常在你长时间按在一个视图上时出现(比如一个列表项)

子菜单 Submenu

这是一个浮动菜单列表,通过在选项菜单或上下文菜单选择菜单项显露出来。不支持嵌套子菜单。

选项菜单 Options Menu

Android开发指南-用户界面-创建菜单

这个选项菜单通过按设备菜单键打开。打开后,出现图标菜单,可包含 6 个菜单项。如果添加多于 6 个菜单项,多出的部分将通过“更多”菜单项在扩展菜单中显示。扩展菜单项在多于 6 个菜单项时自动添加。

选项菜单应该包含应用程序的基本功能以及任何必要的浏览项(例如,返回桌面或应用程序设置)。你还可以通过增加子菜单 Submenus 来组织主题和包含额外的菜单功能。

当菜单第一次被打开时,系统会调用活动 onCreateOptionsMenu() 回调函数。重写该方法并生成传递给你的这个菜单对象。你可以通过扩充定义在 XML 文件中的一个菜单资源或者通过为你想要的每一个菜单项调用 add() 方法生成这个菜单。这个方法增加一个菜单项 MenuItem ,并返回新创建的对象。你可以用返回的 MenuItem 来设置附加属性如图标,快捷键,意图以及这个菜单项的其它设置。

有多个 add() 方法。通常,你会使用接受一个 itemId 参数的那个。这是一个唯一的整数,允许你在回调函数中识别这个 item

当一个菜单项从选项菜单中被选择时,你会接收到一个 onOptionsItemSelected() 回调。这个回调传给你选中的 MenuItem 你可以通过请求 itemId getItemId() 来识别它,这将返回 add() 方法分配的整数。一旦你识别了这个菜单项,就可以采取合适的动作。

下面是一个活动里的例子,其中我们创建了一个选项菜单并处理菜单项的选择:

      
        
          
            /* Creates the menu items */
          
        
      
    
      
        
          
            public boolean onCreateOptionsMenu(Menu menu) {
          
        
      
    
      
        
          
            
            
            menu.add(0, MENU_NEW_GAME, 0, "New Game");
          
        
      
    
      
        
          
            
            
            menu.add(0, MENU_QUIT, 0, "Quit");
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            }
          
        
      
    
      
        
        
      
    
      
        
          
            /* Handles item selections */
          
        
      
    
      
        
          
            public boolean onOptionsItemSelected(MenuItem item) {
          
        
      
    
      
        
          
            
            
            switch (item.getItemId()) {
          
        
      
    
      
        
          
            
            
            case MENU_NEW_GAME:
          
        
      
    
      
        
          
            
            
            newGame();
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            
            
            case MENU_QUIT:
          
        
      
    
      
        
          
            
            
            quit();
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            
            
            }
          
        
      
    
      
        
          
            
            
            return false;
          
        
      
    
      
        
          
            }
          
        
      
    

这个 add() 方法有四个参数: groupId , itemId , order , title groupId 允许你关联这个菜单到一个菜单组中(更多参见下面的菜单组 Menu groups - 这个例中,我们忽略掉它。 itemId 是用来识别菜单项的唯一的整数,在回调函数中使用。 order 允许我们定义菜单的显示顺序 - 缺省情况下,它们以添加时的顺序排列。 title 当然是菜单的名字(可以是一个字符串资源,为了本地化更加方便,建议你使用资源)。

提示 : 如果你有一些可以以一个标题归类的菜单项,考虑以子菜单 Submenu 的方式组织它们。

增加图标 Adding icons

图标也可以通过 setIcon() 函数被添加到菜单项中。

      
        
          
            menu.add(0, MENU_QUIT, 0, "Quit")
          
        
      
    
      
        
          
            
            
            .setIcon(R.drawable.menu_quit_icon);
          
        
      
    

修改菜单 Modifying the menu

如果有些时候你想在选项菜单被打开的时候 re-write 它,可以 override onPrepareOptionsMenu() 方法,该方法在每一次菜单被打开的时候调用。它将传递给你菜单对象,就像回调一样。这对于根据应用程序状态调整菜单选项很有用。

注意 : 当改变菜单项时,根据当前选择的 item 来这样做是一个不好的行为。记住,在触摸模式中,将不会有一个选择或聚焦的 item 。相反,当你想基于 UI 中的某个特定 item 来提供功能时,你应该使用一个 Context Menu 来完成这种行为。

上下文菜单 Context Menu

Android 的上下文菜单在概念上和 PC 软件的右键菜单类似。当一个视图注册到一个上下文菜单时,执行一个在该对象上的“长按”(按住不动差不多两秒钟)动作,将出现一个提供相关功能的浮动菜单。上下文菜单可以被注册到任何视图对象中,不过,最常见的是用于列表视图 ListView item ,在按中列表项时,会转换其背景色而提示将呈现上下文菜单。 (电话联系人列表提供了关于这个特性的一个很好的例子)。

注意:上下文菜单项不支持图标或快捷键。

为了创建一个上下文菜单,你必须重写这个活动的上下文菜单回调函数: onCreateContextMenu() onContextItemSelected() 。在回调函数 onCreateContextMenu() 里,你可以通过使用一个 add() 方法来添加菜单项,或者通过扩充一个定义在 XML 中的菜单资源。然后,通过 registerForContextMenu() 为这个视图注册一个上下文菜单 ContextMenu .

比如,下面的代码可以被用到 Notepad 应用程序中来为列表中的每一个注释添加一个上下文菜单:

      
        
          
            public void onCreateContextMenu(ContextMenu menu, View v,
          
        
      
    
      
        
          
            
            
            ContextMenuInfo menuInfo) {
          
        
      
    
      
        
          
            
            
            super.onCreateContextMenu(menu, v, menuInfo);
          
        
      
    
      
        
          
            
            
            menu.add(0, EDIT_ID, 0, "Edit");
          
        
      
    
      
        
          
            
            
            menu.add(0, DELETE_ID, 0,
            
            
            "Delete");
          
        
      
    
      
        
          
            }
          
        
      
    
      
        
        
      
    
      
        
          
            public boolean onContextItemSelected(MenuItem item) {
          
        
      
    
      
        
          
            
            
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
          
        
      
    
      
        
          
            
            
            switch (item.getItemId()) {
          
        
      
    
      
        
          
            
            
            case EDIT_ID:
          
        
      
    
      
        
          
            
            
            editNote(info.id);
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            
            
            case DELETE_ID:
          
        
      
    
      
        
          
            
            
            deleteNote(info.id);
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            
            
            default:
          
        
      
    
      
        
          
            
            
            return super.onContextItemSelected(item);
          
        
      
    
      
        
          
            
            
            }
          
        
      
    
      
        
          
            }
          
        
      
    

onCreateContextMenu() 中,除了给出将添加 MenuItems ContextMenu 外,还需要给定选中的视图和一个上下文菜单信息 ContextMenuInfo 对象,该对象提供了选中对象的附加信息。在本例中, onCreateContextMenu() 没做什么特别的事 - 只是添加了一些菜单项。在 onContextItemSelected() 回调函数中,我们从 MenuItem 中请求 AdapterContextMenuInfo ,该对象提供当前选中项的信息。我们从中所要的只是这个选中项的列表 ID ,所以无论编辑还是删除一个注释,我们通过这个对象的 AdapterContextMenuInfo.info 字段来找到该 ID 。这个 ID 被传递给 editNote() deleteNote() 方法来执行相应的动作。

现在,要为一个列表视图中的所有项注册上下文菜单,我们可以传递整个的列表视图对象给 registerForContextMenu(View) 方法:

      
        
          
            registerForContextMenu(getListView());
          
        
      
    

记住,你可以传递任何视图对象来注册一个上下文菜单。这里, getListView() 返回这个被用于 Notepad 应用程序的列表活动 ListActivity 中的列表视图对象。这样,这个列表中的任何 item 都被注册到这个上下文菜单。

子菜单 Submenus

一个子菜单可以被添加进任何菜单中,但不能加入另外的子菜单中。当你的应用程序有很多功能可以按主题组织的时候,这将非常有用,就好比 PC 应用程序的菜单栏(文件,编辑,视图,等)。

子菜单通过 addSubMenu() 加入到已有的菜单中而创建。该函数会返回一个子菜单 SubMenu 对象(菜单 Menu 的一个扩展)。然后你可以通过调用 add() 方法给这个菜单添加其他项,例如:

      
        
          
            public boolean onCreateOptionsMenu(Menu menu) {
          
        
      
    
      
        
          
            
            
            boolean result = super.onCreateOptionsMenu(menu);
          
        
      
    
      
        
        
      
    
      
        
          
            
            
            SubMenu fileMenu = menu.addSubMenu("File");
          
        
      
    
      
        
          
            
            
            SubMenu editMenu = menu.addSubMenu("Edit");
          
        
      
    
      
        
          
            
            
            fileMenu.add("new");
          
        
      
    
      
        
          
            
            
            fileMenu.add("open");
          
        
      
    
      
        
          
            
            
            fileMenu.add("save");
          
        
      
    
      
        
          
            
            
            editMenu.add("undo");
          
        
      
    
      
        
          
            
            
            editMenu.add("redo");
          
        
      
    
      
        
        
      
    
      
        
          
            
            
            return result;
          
        
      
    
      
        
          
            }
          
        
      
    

子菜单中选择项的回调动作将由父菜单的回调方法处理。比如上面的例子,子菜单中的选择将由 onOptionsItemSelected() 回调处理。

你也可以在 XML 中定义父菜单时增加子菜单。

XML 里定义菜单 Define Menus in XML

就像 Android 用户界面布局一样,你可以在 XML 文件中定义菜单,然后在你菜单的 onCreate...() 回调函数中扩充它们。这使得你的应用程序代码简洁而且把更多的界面设计分离到 XML 文件中,这更容易形象化。

首先,在你的工程 res/ 的目录下创建一个新的目录叫 menu 。你所有定义应用程序菜单的 XML 文件都应该放在这里。

在一个菜单 XML 布局中,有三个合法的元素: <menu> <group> <item> item group 必须是菜单的子元素,而 item 元素还可以是 group 的子元素,并且另外一个菜单元素可以是一个 item 的子元素(来创建一个子菜单)。当然,任何文件的根元素必须是一个 menu 元素。

作为一个例子,我们将定义和在上面的选项菜单 Options Menu 章节中所创建的相同的菜单,我们首先在目录 res/menu/ 里创建一个名为 options_menu.xml 的文件。

      
        
          
            <menu xmlns:android="http://schemas.android.com/apk/res/android">
          
        
      
    
      
        
          
            
            
            <item android:id="@+id/new_game"
          
        
      
    
      
        
          
            
            
            android:title="New Game" />
          
        
      
    
      
        
          
            
            
            <item android:id="@+id/quit"
          
        
      
    
      
        
          
            
            
            android:title="Quit" />
          
        
      
    
      
        
          
            </menu>
          
        
      
    

然后,在 onCreateOptionsMenu() 方法里,我们通过 MenuInflater.inflate() 方法扩充这个资源:

      
        
          
            public boolean onCreateOptionsMenu(Menu menu) {
          
        
      
    
      
        
          
            
            
            MenuInflater inflater = getMenuInflater();
          
        
      
    
      
        
          
            
            
            inflater.inflate(R.menu.options_menu, menu);
          
        
      
    
      
        
          
            
            
            return true;
          
        
      
    
      
        
          
            }
          
        
      
    

getMenuInflater() 方法返回我们活动上下文的 MenuInflater 然后我们调用 inflate() ,传递给它一个指向我们菜单资源的指针以及回调给出的菜单对象。

尽管和在 onCreateOptionsMenu() 创建菜单比较起来,上面的例子看起来做了更多的事情,但是如果处理更多的菜单项,这将省掉很多麻烦并让你的代码简洁。

你可以通过把 item 元素打包进一个 group 中来定义菜单组 menu groups ,然后通过在一个 item 中嵌入另外一个 menu 来创建子菜单。每个元素都支持必需的属性来控制快捷键,复选框,图标,以及更多特性。

要了解这些属性和更多的 XML 语法,请参见可用资源类型 Available Resource Types 中的相关主题。

Android开发指南-用户界面-创建菜单


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论