menu(菜单)

Posted yh_android_blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了menu(菜单)相关的知识,希望对你有一定的参考价值。

概述

在许多类型的应用中,菜单是一个常用的用户界面组件。为提供一个熟悉且一致的用户体验,在你的应用中,应该使用Menu API 来呈现用户操作和其它操作。 始于安卓3.0(api 11),安卓机器不再直接提供一个 Menu按钮。安卓应用应该从 依赖于传统的6选项菜单板 迁移到 提供一个action bar 来提高公共的用户操作。 对一些菜单项来说, 尽管 设计和用户体验发生了改变,定义一组操作和选项的语义仍旧是基于 Menu API的。该文件展示了如何创建三种基本类型的菜单和在所有安卓版本上的操作演示: 选择菜单(Options menu)和操作栏(action bar )           options menu  是activity上的菜单项的主要集合。在这些地方,你应该放置对app有全局影响力的操作,例如   "Search," "Compose email," and "Settings."          如果你在安卓2.3或更低版本上开发,用户可以通过点击menu按钮来显示选项菜单板。
         在安卓3.0或更高版本,选项菜单上的选项都呈现在action bar上,作为一个联合的显示出来的操作项和溢出选项。从安卓3.0开始,反对使用menu按钮(一些设备上没有),因此你应该迁移到action bar上来提供操作入口和其它选项。
           查看关于 #创建选项菜单(Options Menu) 的相关章节。 上下文菜单(Context menu )和上下文的操作模式( contextual action mode)          一个上下文菜单是一个浮动菜单(floating menu),当用户执行长按元素动作时出现。它提供影响选中的内容或背景框架的操作。
         在安卓3.0或更高版本开发时, 在选中内容时, 你应该改为使用  上下文操作模式( contextual action mode )来提供操作。该模式 在屏幕顶部的条上 展示影响所选内容的操作项,并允许用户进行多选。           查看 #创建上下文相关菜单(Contextual Menus) 的相关章节 弹出菜单(Popup menu)          一个弹出菜单用一个垂直列表展示了一列选项,它停留在一个用来显示菜单的view上。它很好的提供一个涉及特别内容的一些溢出操作 或 提供二级命令选项。弹出菜单中的操作不应该直接影响相关的内容---取决于语境操作。相反,弹出菜单是在你的activity内的相关内容上扩展一些操作。
         查看 #创建弹出菜单(Popup Menu) 的相关章节

 在XML文件中定义菜单

对于所有的菜单类型,安卓提供了一个标准的xml格式来定义菜单项。来代替你在activity中使用代码构造,你需要在xml  menu 资源文件夹下定义一个菜单和它的所有的选项。在你的activity或fragment中可以展开该menu资源文件(通过一个menu 对象加载)。 使用差点资源文件是一个好的实践,原因如下:
  • 在XML中容易看清菜单结构
  • 你的应用行为代码和菜单内容分离了开来
  • 允许你为 不同的版本,不同大小的屏幕,和不同的结构来创建不同的菜单
为定义该菜单,在你的 res/menu/ 文件夹下创建一个XML文件,并且使用如下元素构造该菜单: <menu>
定义一个menu,它是一个菜单项的容器。一个<menu>元素必须是文件的根节点,可以容纳一个或多个<item>和<group>元素。
<item>
创建一个menuItem,它代表一个简单的菜单项。该元素可以包含一个嵌套的<menu>来创建一个子菜单。
<group>
可选项,<item>元素的不可见容器。它允许你将菜单项分类这样就可以分享属性,如活动状态和可见性。更多信息,请看【下文】的相关章节
这里有个menu的例子,命名为 game_menu.xml :
   
    
     <?xml version="1.0" encoding="utf-8"?>
    
    
     <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
    
         <item android:id="@+id/new_game"
    
    
               android:icon="@drawable/ic_new_game"
    
    
               android:title="@string/new_game"
    
    
               android:showAsAction="ifRoom"/>
    
    
         <item android:id="@+id/help"
    
    
               android:icon="@drawable/ic_help"
    
    
               android:title="@string/help" />
    
    
     </menu>
    
   
该<item>元素提供的一些属性可用来定义一个项目的外观和行为。在上面item使用的属性如下: android:id
一个唯一指向该项的资源ID,当用户选择它时,允许应用识别出该项。
android:icon
一个drawable的引用,用来绘制菜单项的icon
android:title
一个string的引用,用来作为菜单项的title
android:showAsAction
具体说明,何时或如何在action bar上作为action item 来显示该菜单项。
这些就是你需要使用的最重要的属性,但还有更多的可用属性。更多它支持的属性请查看 Menu Resource  文档。 你可以在任何菜单的item(除了子菜单)中添加一个子菜单,通过添加<menu >元素作为<item>元素的子节点。当你的应用有许多方法组织在一个主题时,使用子菜单,如PC应用菜单的菜单项(文件,编辑,视图,等)。例子:
   
    
     <?xml version="1.0" encoding="utf-8"?>
    
    
     <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
    
         <item android:id="@+id/file"
    
    
               android:title="@string/file" >
    
    
             <!-- "file" submenu -->
    
    
             <menu>
    
    
                 <item android:id="@+id/create_new"
    
    
                       android:title="@string/create_new" />
    
    
                 <item android:id="@+id/open"
    
    
                       android:title="@string/open" />
    
    
             </menu>
    
    
         </item>
    
    
     </menu>
    
   
在你的activity 中使用菜单,你需要使用   MenuInflater.inflate() 展开该菜单资源文件(将xml 资源转换为可编程的对象)。在下面的章节,你会看到如何展开各种类型的菜单。

创建选项菜单(Options Menu)

选项菜单 是一个包含 了当前活动相关内容的操作和其它选项的地方,例如   "Search," "Compose email," and "Settings." 你的选 项菜单在何处显示取决于你安卓的版本: 如果在安卓2.3.x (API 10)或更低版本开发,当用户点击Menu 按钮时,你的选项菜单的内容显示在屏幕的底部,如图1所示。打开时,第一个显示出来的是icon菜单,其中有六个菜单项。如果你的菜单包括的菜单项超过六个,安卓只放置六个项目,其它的放入溢出菜单,可以通过选择more菜单项打开。 如果你在安卓3.0(API 11)或更高版本上开发,选项菜单中的项目会在action bar上应用。默认的,系统放置了所有的项目在溢出菜单栏,用户可以点击在action bar 右部的溢出菜单按钮来显示(或者通过点击设备的menu 按钮,如果可用的话)。为了能够快速使用重要的操作,你可以 中提升少数项目显示在 在action bar中,通过在相应的<item >元素中添加 android:showAsAction="ifRoom"。 更多关于action items 和其它action bar 的行为,请看 Action Bar  导航。 注:尽管你不在安卓3.0或更高版本上开发,你可以构造自己的action bar 布局来实现相似的效果。例如如何支持老版本的安卓上使用 action bar ,看   Action Bar Compatibility  示例。
可以从你的activity 子类或fragment 子类中声明你的选项菜单的选项。如果你在activity 和fragemen 中都声明了选项菜单项,它们会联合显示在UI上。先显示activity的item ,然后就是按加入顺序显示每个fragment 的item 。如果需要,你可以在每一个<item>中添加 android:orderInCategory  属性来对item 重新排序。 为activity 指定一个选项菜单,重写 onCreateOptionsMenu()  (fragment 提供了 onCreateOptionsMenu()回调方法 )。在该方法中,你可以解析你的菜单资源文件(在XML中定义)到 Menu 中,该menu由回调函数提供。如下:
   
    
     @Override
    
    
     public boolean onCreateOptionsMenu(Menu menu) 
    
    
         MenuInflater inflater = getMenuInflater();
    
    
         inflater.inflate(R.menu.game_menu, menu);
    
    
         return true;
    
    
     
    
   
你可以使用 add()  来添加菜单项,使用 findItem()获得item的引用来修改item 的属性,这些方法都在 MenuItem  APIs.中。 如果你在安卓2.3.x和更低版本上开发, 当用户第一次打开菜单时, 系统调用 onCreateOptionsMenu() 来创建选项菜单。如果你在安卓3.0和更高版本上开发,当activity 启动,系统调用 onCreateOptionsMenu(),为了在action bar 中显示item 。

处理点击事件

当用户从你的选项菜单中选择一个项目时(包括actin bar 中的action item ),系统调用你activity 中的 onOptionsItemSelected()  方法。该方法传递了被选中的menuItem。你可以通过调用 getItemId()来识别item,该方法返回一个菜单项的唯一ID(通过资源文件下的 android:id  或在 add() 方法中给定的integer数据 定义 )。你可以匹配这个ID来了解菜单项用来执行的适当操作。如:
   
    
     @Override
    
    
     public boolean onOptionsItemSelected(MenuItem item) 
    
    
         // Handle item selection
    
    
         switch (item.getItemId()) 
    
    
             case R.id.new_game:
    
    
                 newGame();
    
    
                 return true;
    
    
             case R.id.help:
    
    
                 showHelp();
    
    
                 return true;
    
    
             default:
    
    
                 return super.onOptionsItemSelected(item);
    
    
         
    
    
     
    
   
当你成功的处理了一个菜单项,返回true 。如果你没有处理该菜单项,你需要调用父类的实现方法 onOptionsItemSelected()  (该默认实现返回的是false)
如果你的activity 中包含了fragment ,系统首先调用activty 中的 onOptionsItemSelected(),然后是每一个fragment (根据fragment 添加的顺序)直到一个返回true 或者所有的fragment 都被调用。 技巧:安卓3.0添加了在xml文件中为菜单项定义on-click 事件的能力,使用 android:onClick  属性。该属性的值必须和在使用该菜单的activity 中定义的方法名相同。方法必须为public 并且接受一个简单的 MenuItem参数——当系统调用该方法时,该参数传递的是被点击的菜单项。更多信息和示例,查看 Menu Resource  文档。 技巧:如果你的应用包含多个activity ,并且其中的一些提供了相同的选项菜单,考虑创建一个activity除了 onCreateOptionsMenu() and  onOptionsItemSelected()  方法之外,什么方法都不去实现。然后让每个可能有相同选项菜单的activity 都继承该类。这样,你可以组织一个代码集合来处理菜单操作和每一个子类的菜单行为。如果你想在每个子类中添加菜单项,在相应的activity 中覆盖 onCreateOptionsMenu()  activity 调用 super.onCreateOptionsMenu(menu)  这样原始的菜单项就被创建了,然后通过 menu.add()  添加新的菜单项。你也可以为每一个菜单项覆盖父类的行为。

在运行时更改菜单项

在系统调用 onCreateOptionsMenu()之后,它保留一个menu的引用并且不在调用 onCreateOptionsMenu(),除非一些原因使得菜单无效。然而,你可以使用 onCreateOptionsMenu()只用来创建初始菜单状态,并且在activity生命周期内不会发生改变。 如果你想在activity生命周期内基于事件来更改菜单选项,你可以在 onPrepareOptionsMenu()  方法中做些什么事情。该方法传递你的menu对象作为当前状态,所以你可以更改它,例如增加,移除或取消items(fragments 提供了 onPrepareOptionsMenu() 方法 在安卓2.3.x和更低版本,每次用户打开选项菜单时(按下menu按钮),系统将会调用 onPrepareOptionsMenu()   在安卓3.0和更高版本,选项菜单认为是经常被开启的,当菜单项在action bar上显示时。当一件事件发生并且你希望执行一个菜单的更新,你必须调用 invalidateOptionsMenu()  来请求系统调用 onPrepareOptionsMenu() . :你不该在view获得焦点的时候改变选项菜单上的选项。当在触摸模式(用户没有使用轨迹球或方向键),view不能获取焦点,因此你不应该使用焦点作为在选项菜单中更改选项的基础。如果你想在上下文相关的view中提供菜单项,使用   Context Menu .

创建上下文相关菜单(Contextual Menus)


一个上下文相关菜单提供了影响 特别项或UI中上下文frame 的操作。你可以为任何view提供一个上下文菜单,但是它们通常被用在 ListView GridView other  或其它 可集合的view上,这样用户可以为每个项目直接执行操作。 两个方法提供一个上下文相关操作: 在浮动上下文菜单( floating context menu )中.菜单显示在一个浮动列表中(和dialog相似)当用户在 被声明提供一个上下文菜单的 view上执行长按操作时,菜单就会显示。此时用户可以在一个选项中执行一个上下文相关操作。 在上下文操作模式( contextual action mode )中.该模式是系统实现的一个 ActionMode 在屏幕的上方 展示了一个上下文相关的action bar ,在该action bar上的选项可以影响被选择的项。当该模式开始工作,用户可以一次执行多个选项操作(如果你的应用允许) :上下文操作模式在安卓3.0和更高版本上可用,这是个显示上下文相关操作的更好技巧。如果你的应用版本在3.0及其以下,你可以后退到一个浮动上下文菜单。

创建浮动上下文菜单(floating context menu )

为提供一个浮动上下文菜单: 1.注册一个view,上下文菜单通过调用 registerForContextMenu()  并且传递这个view。      如果你的activity使用了 ListView  或 GridView  并且你想要为每一项都提供相同的上下文菜单,通过调用 registerForContextMenu() .传递该   ListView  or  GridView  来在上下文菜单中注册所有的项目。 2.在你的 Activity  或 Fragment .中 实现 onCreateContextMenu()  方法。当被注册的view接受到一个长按事件,系统调用你的 onCreateContextMenu()方法。这是你定义菜单项的地方,通常通过展开一个菜单资源文件。如下:
   
    
     @Override
    
    
     public void onCreateContextMenu(ContextMenu menu, View v,
    
    
                                     ContextMenuInfo menuInfo) 
    
    
         super.onCreateContextMenu(menu, v, menuInfo);
    
    
         MenuInflater inflater = getMenuInflater();
    
    
         inflater.inflate(R.menu.context_menu, menu);
    
    
     
    
   
MenuInflater  允许你从一个菜单资源中展开该上下文菜单。该回调方法中包含一个用户选中的 view 和一个关于提供了被选择项的额外消息的 ContextMenu.ContextMenuInfo  对象。如果你的activity有多个view,并且都提供了不同的上下文菜单,你或许要使用这些参数来决定展开哪个上下文菜单。 3.实现 onContextItemSelected() .     当用户选择了一个菜单项,系统调用该方法让你执行相应的方法。如下:
   
    
     @Override
    
    
     public boolean onContextItemSelected(MenuItem item) 
    
    
         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    
    
         switch (item.getItemId()) 
    
    
             case R.id

以上是关于menu(菜单)的主要内容,如果未能解决你的问题,请参考以下文章

android menu 有啥用

Android 中实现上下文菜单(Context menu)详解

SwiftUI上下文菜单(Context Menu)内容不随对象状态刷新的解决

UI控件之菜单(Menu)

android中的菜单menu可以在屏幕上一直显示吗

一起学Android之Menu