Android Menu的几种实现方式

android menu实现方式有好几种,有时候容易弄混淆,下面来总结一下Menu的几种用法。

一.options Menu

options Menu 就是最常用的菜单,在3.0版本以前,按物理menu键,弹出options menu,在3.0版本以后,则和actionBar结合使用

创建options Menu的方法:

1 定义菜单资源文件

在res/menu/目录下,创建菜单资源文件game_menu.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:id="@+id/new_game"  
  4.           android:icon="@drawable/ic_new_game"  
  5.           android:title="@string/new_game"  
  6.           android:showAsAction="ifRoom"/>  
  7.     <item android:id="@+id/help"  
  8.           android:icon="@drawable/ic_help"  
  9.           android:title="@string/help" />  
  10. </menu>  
在菜单资源文件中主要包含3个标签

<menu> <item> <group>

一个item表示一个菜单子项,一个group中可以包含若干个item

当一个菜单的条目很多的时候,我们也可以使用子菜单:可以将一个<menu>作为另一个菜单的<item>嵌套

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android">  
  3.     <item android:id="@+id/file"  
  4.           android:title="@string/file" >  
  5.         <!-- "file" submenu -->  
  6.         <menu>  
  7.             <item android:id="@+id/create_new"  
  8.                   android:title="@string/create_new" />  
  9.             <item android:id="@+id/open"  
  10.                   android:title="@string/open" />  
  11.         </menu>  
  12.     </item>  
  13. </menu>  

2 要想在Activity中使用菜单资源,必须onCreateOptionsMenu()方法,该方法主要用于创建菜单

  1. @Override  
  2. public boolean onCreateOptionsMenu(Menu menu) {  
  3.     MenuInflater inflater = getMenuInflater();  
  4.     inflater.inflate(R.menu.game_menu, menu);  
  5.     return true;  
  6. }  

我们同样也可以使用findItem()和add()方法在代码中创建菜单,在30.版本之前,在用户第一次打开菜单的时候创建菜单,执行该方法,而在3.0以后的版本则是在activity创建的时候就执行该方法,创建菜单。

3 当创建好菜单资源后,就要处理菜单的事件。当用户选择一个菜单之后,包括actionBar之上的action item,系统哦你就会回调onOptionsItemSelected()方法,然后在该方法中处理点击事件即可:

  1. @Override  
  2. public boolean onOptionsItemSelected(MenuItem item) {  
  3.     // Handle item selection  
  4.     switch (item.getItemId()) {  
  5.         case R.id.new_game:  
  6.             newGame();  
  7.             return true;  
  8.         case R.id.help:  
  9.             showHelp();  
  10.             return true;  
  11.         default:  
  12.             return super.onOptionsItemSelected(item);  
  13.     }  
  14. }  


如果在activity中包含fragment,系统会首先调用activity的onOptionsItemSelected()方法,然后才会点用fragment 的onOptionsItemSelected()方法,直到有返回true或者调用完所有的onOptionsItemSelected()方法。

4 很多时候我们需要动态改变菜单的内容,这时候我们应该怎么修改呢?在onCreateOptionsMenu(),方法中修改吗?上边我们讲过onCreateOptionsMenu(),方法在创建菜单时候只执行一次,所以该方法显然不合适,应该使用onPrepareOptionsMenu()方法,2.3版本以前,每次打开菜单的时候都会调用onPrepareOptionsMenu()方法,在3.0以后的版本上,想要更新菜单,调用该方法,则必须调用invalidateOptionsMenu()方法,请求系统去调用onPrepareOptionsMenu()方法。

二.Context Menu

Context menu是一个浮动的列表菜单,要想创建context menu 首先需要相关的View调用registerForContextMenu()注册事件,如果是listView或者gridView的话,可能需要每个item都调用该方法注册事件。

创建菜单,要在Activity或者Fragment中实现onCreateMenu()方法。

  1. @Override  
  2. public void onCreateContextMenu(ContextMenu menu, View v,  
  3.                                 ContextMenuInfo menuInfo) {  
  4.     super.onCreateContextMenu(menu, v, menuInfo);  
  5.     MenuInflater inflater = getMenuInflater();  
  6.     inflater.inflate(R.menu.context_menu, menu);  
  7. }  

最后同样也是实现选中或点击事件,实现 onContextItemSelected()

  1. @Override  
  2. public boolean onContextItemSelected(MenuItem item) {  
  3.     AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();  
  4.     switch (item.getItemId()) {  
  5.         case R.id.edit:  
  6.             editNote(info.id);  
  7.             return true;  
  8.         case R.id.delete:  
  9.             deleteNote(info.id);  
  10.             return true;  
  11.         default:  
  12.             return super.onContextItemSelected(item);  
  13.     }  
  14. }  

三.Contextual Action Mode

contextual Action mode 菜单是对ActionMode的实现,当激活action mode菜单的时候,一个contextual action bar 出现在屏幕顶端的位置,上面显示可以对当前选中条目操作的选项。当用户选择的条目为0,按下 back键,或者选中Action mode菜单左上角的done按钮, action mode 菜单消失。

android官方一般建议以下两种情况下使用并激活action mode菜单

1 一个view的长按事件

2 checkbox选中

要想在自己的应用中使用action mode 菜单,需要以下几个步骤:

1 实现ActionMode.Callback()接口,在方法中要指定contextual action bar 上的操作菜单选项,同时还要实现菜单选项的点击事件。

  1. private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {  
  2.   
  3.     // Called when the action mode is created; startActionMode() was called  
  4.     @Override  
  5.     public boolean onCreateActionMode(ActionMode mode, Menu menu) {  
  6.         // Inflate a menu resource providing context menu items  
  7.         MenuInflater inflater = mode.getMenuInflater();  
  8.         inflater.inflate(R.menu.context_menu, menu);  
  9.         return true;  
  10.     }  
  11.   
  12.     // Called each time the action mode is shown. Always called after onCreateActionMode, but  
  13.     // may be called multiple times if the mode is invalidated.  
  14.     @Override  
  15.     public boolean onPrepareActionMode(ActionMode mode, Menu menu) {  
  16.         return false// Return false if nothing is done  
  17.     }  
  18.   
  19.     // Called when the user selects a contextual menu item  
  20.     @Override  
  21.     public boolean onActionItemClicked(ActionMode mode, MenuItem item) {  
  22.         switch (item.getItemId()) {  
  23.             case R.id.menu_share:  
  24.                 shareCurrentItem();  
  25.                 mode.finish(); // Action picked, so close the CAB  
  26.                 return true;  
  27.             default:  
  28.                 return false;  
  29.         }  
  30.     }  
  31.   
  32.     // Called when the user exits the action mode  
  33.     @Override  
  34.     public void onDestroyActionMode(ActionMode mode) {  
  35.         mActionMode = null;  
  36.     }  
  37. };  
2,调用   startActionMode()  来激活action mode菜单。

  1. someView.setOnLongClickListener(new View.OnLongClickListener() {  
  2.     // Called when the user long-clicks on someView  
  3.     public boolean onLongClick(View view) {  
  4.         if (mActionMode != null) {  
  5.             return false;  
  6.         }  
  7.   
  8.         // Start the CAB using the ActionMode.Callback defined above  
  9.         mActionMode = getActivity().startActionMode(mActionModeCallback);  
  10.         view.setSelected(true);  
  11.         return true;  
  12.     }  
  13. });  
3,如何在ListView或gridView中实现批量任务操作。
要实现   AbsListView.MultiChoiceModeListener接口,在该接口中创建action mode 菜单,指定contextual action bar操作选项,并实现改操作的点击事件和其他回调方法,和ActionMode.Callback()差不多。

通过setMultiChoiceModeListener()注册监听事件

调用setChoiceMode()方法,参数为 CHOICE_MODE_MULTIPLE_MODAL

  1. ListView listView = getListView();  
  2. listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);  
  3. listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {  
  4.   
  5.     @Override  
  6.     public void onItemCheckedStateChanged(ActionMode mode, int position,  
  7.                                           long id, boolean checked) {  
  8.         // Here you can do something when items are selected/de-selected,  
  9.         // such as update the title in the CAB  
  10.     }  
  11.   
  12.     @Override  
  13.     public boolean onActionItemClicked(ActionMode mode, MenuItem item) {  
  14.         // Respond to clicks on the actions in the CAB  
  15.         switch (item.getItemId()) {  
  16.             case R.id.menu_delete:  
  17.                 deleteSelectedItems();  
  18.                 mode.finish(); // Action picked, so close the CAB  
  19.                 return true;  
  20.             default:  
  21.                 return false;  
  22.         }  
  23.     }  
  24.   
  25.     @Override  
  26.     public boolean onCreateActionMode(ActionMode mode, Menu menu) {  
  27.         // Inflate the menu for the CAB  
  28.         MenuInflater inflater = mode.getMenuInflater();  
  29.         inflater.inflate(R.menu.context, menu);  
  30.         return true;  
  31.     }  
  32.   
  33.     @Override  
  34.     public void onDestroyActionMode(ActionMode mode) {  
  35.         // Here you can make any necessary updates to the activity when  
  36.         // the CAB is removed. By default, selected items are deselected/unchecked.  
  37.     }  
  38.   
  39.     @Override  
  40.     public boolean onPrepareActionMode(ActionMode mode, Menu menu) {  
  41.         // Here you can perform updates to the CAB due to  
  42.         // an invalidate() request  
  43.         return false;  
  44.     }  
  45. });  

四.Pop Menu

Pop menu 总是铆钉在某一个view的下方,如果下方没有地方的话,会在上边或其他的地方。

要想使用pop menu,首先也要定义菜单资源,然后使用PopMenu的构造方法,构造PopMenu需要在构造方法中传入context 和 需要铆钉的View

  1. public void showPopup(View v) {  
  2.     PopupMenu popup = new PopupMenu(this, v);  
  3.     MenuInflater inflater = popup.getMenuInflater();  
  4.     inflater.inflate(R.menu.actions, popup.getMenu());  
  5.     popup.show();  
  6. }  

这里需要铆钉的View 就是调用popMenu的Button

  1. <ImageButton  
  2.     android:layout_width="wrap_content"   
  3.     android:layout_height="wrap_content"   
  4.     android:src="@drawable/ic_overflow_holo_dark"  
  5.     android:contentDescription="@string/descr_overflow_button"  
  6.     android:onClick="showPopup" />  
当选中popMenu的一个条目或者点击popMenu以外的地方的时候,PopMenu就会消失。要想处理消失时的事件需要监听 PopupMenu.OnDismissListener .

下一步就是要为popMenu注册点击事件,popup.setOnMenuItemClickListener(this);

处理popMenu的选中事件需要实现PopupMenu.OnMenuItemClickListener 接口。

  1. @Override  
  2. public boolean onMenuItemClick(MenuItem item) {  
  3.     switch (item.getItemId()) {  
  4.         case R.id.archive:  
  5.             archive(item);  
  6.             return true;  
  7.         case R.id.delete:  
  8.             delete(item);  
  9.             return true;  
  10.         default:  
  11.             return false;  
  12.     }  
  13. }  



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值