Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android應用開發入門(三十七)菜單Menu的使用

Android應用開發入門(三十七)菜單Menu的使用

編輯:Android開發實例

前言

  本文講解一下菜單Menu的使用。菜單在windows應用中使用十分廣泛,幾乎所有的windows應用都有菜單,Android中也加入了菜單的支持。從官方文檔了解到,從Android3.0(API level 11)開始,Android設備不再要求提供一個專門的菜單按鈕,轉而推薦使用ActionBar。所以現在市面上很多新設備使用三個虛擬按鍵,並不再額外提供菜單按鈕,但是按鈕的使用也是有些地方可以借鑒的。

  因為Android版本的發展,對於菜單的支持各個版本有很大的區別,而Android3.0是個分水嶺,大概可以分為下面三類:

  • OptionMenu和ActionBar:一些操作的集合,如果開發的平台在Android3.0之上,推薦使用ActionBar,如果開發的平台在Android2.3或之下,還是可以使用OptionMenu的。
  • ContextMenu和ActionMode:ContextMenu是一個浮動的窗口形式展現一個選項列表,ActionMode是一個顯示在屏幕頂部的操作欄,允許用戶選擇多個選項,ActionMode在Android3.0之後才有支持。
  • Pupop Menu:PopupMenu是固定在View上的模態菜單,以彈出的方式顯示,在Android3.0之後才有支持。

  

在XML中定義一個菜單

  Android提供了標准的XML格式的資源文件來定義菜單項,並且對所有菜單類型都支持,推薦使用XML資源文件來定義菜單,之後再把它Inflater到Activity或者Fragment中,而不是在Activity中使用代碼聲明。

  而菜單的XML資源文件,需要創建在/res/menu/目錄下,並且包含一下幾個元素:

  • <menu>:定義一個Menu,是一個菜單資源文件的根節點,裡面可以包含一個或者多個<item>和<group>元素。
  • <item>:創建一個MenuItem,代表了菜單中一個選項。
  • <group>:對菜單項進行分組,可以以組的形式操作菜單項。

  <item>元素除了常規的id、icon、title屬性的支持,還有一個重要的屬性:android:showAsAction,這個屬性是起兼容性的,描述了在Android的高版本中,菜單項何時以何種方式加入到ActionBar中。

  <group>是對菜單進行分組,分組後的菜單顯示效果並沒有區別,唯一的區別在於可以針對菜單組進行操作,這樣對於分類的菜單項,操作起來更方便,提供如下的操作:

  • Menu.setGroupCheckable():菜單組內的菜單是否都可選。
  • Menu.setGroupVisible():是否隱藏菜單組的所有菜單。
  • Menu.setGroupEnabled():菜單組的菜單是否有用。

  如果菜單項需要單選或者多選,可以使用android:checkableBehavior屬性設置,它可以對單個<item>或者<group>設置一個組,這個屬性接受三個參數:single,單選;all,多選,none,沒有Checked的選項,默認。

  當創建好一個XML菜單資源文件之後,可以使用MenuInflater.inflate()方法填充菜單資源,使XML資源變成一個可編程的對象。

 

OptionMenu

  OptionMenu,選項菜單,必須設備具有菜單按鈕才可以觸發。因為屏幕的限制,最多只能展示六個菜單項,如果定義的菜單項超出了六個,其他的菜單項將被隱藏,第六個菜單將會顯示“更多”,點擊展開更多的菜單。雖說在Android3.0之後不再推薦使用選項菜單,但是如果使用了,在Android3.0之後的設備上,選項菜單項將被默認轉移到ActionBar中,這個可以通過android:showAsAction屬性控制。

  使用OptionMenu需要在Activity或者Fragment中重寫onCreateOptionsMenu(Menu)方法,在這個方法中聲明一個選項菜單。菜單的存在是為了提供操作,所以Activity和Fragment中還提供了一個onOptionsItemSelected(MenuItem)方法,用於響應選項菜單中選中的時候的響應。OptionMenu就是操作一個Menu對象和MenuItem對象。

  下面通過兩個Demo來展示一段選項菜單的使用,分別使用代碼聲明菜單和XML資源文件聲明菜單的方式說明。

  聲明代碼: 

  1. package com.example.menudemo;  
  2.  
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.Menu;  
  7. import android.view.MenuItem;  
  8. import android.view.SubMenu;  
  9. import android.widget.Toast;  
  10.  
  11. public class OptionMenu1Activitty extends Activity {  
  12.  
  13.     @Override 
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         // TODO Auto-generated method stub  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_optionmenu1);  
  18.     }  
  19.  
  20.     @Override 
  21.     public boolean onCreateOptionsMenu(Menu menu) {  
  22.           
  23.         //直接Add菜單選項到Menu中  
  24.         menu.add(1000, 100, 0, "System menu");   
  25.         //獲取添加的菜單選項,然後設置其圖標  
  26.         MenuItem menuItem2=menu.add(1000, 101, 1, "User menu");   
  27.         menuItem2.setIcon(R.drawable.ic_launcher);  
  28.         //獲取添加的菜單選項,增加一個Intent,點擊後轉向IntentActivity  
  29.         MenuItem menuItem3=menu.add(1000, 102, 2, "Intent menu");   
  30.         menuItem3.setIcon(R.drawable.ic_launcher);  
  31.         Intent intent=new Intent(OptionMenu1Activitty.this, IntentActivity.class);  
  32.         menuItem3.setIntent(intent);          
  33.  
  34.         //添加一個SubMenu,點擊後彈出一個子菜單對話框  
  35.         SubMenu submenu=menu.addSubMenu(1000, 103, 3, "Sub menus");  
  36.         submenu.add(1000, 104, 4, "Sub ment1");  
  37.         submenu.add(1000, 105, 4, "Sub ment2");  
  38.         submenu.add(1000, 106, 4, "Sub ment3");  
  39.         return true;  
  40.     }  
  41.       
  42.     @Override 
  43.     public boolean onOptionsItemSelected(MenuItem item) {  
  44.         boolean flag;  
  45.         switch (item.getItemId()) {  
  46.         case 100:  
  47.             Toast.makeText(OptionMenu1Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();  
  48.             flag=true;  
  49.             break;  
  50.         case 101:  
  51.             Toast.makeText(OptionMenu1Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();  
  52.             flag=true;  
  53.             break;  
  54.         case 104:  
  55.             Toast.makeText(OptionMenu1Activitty.this, "selected Sub menu1", Toast.LENGTH_SHORT).show();  
  56.             flag=true;  
  57.         default:  
  58.             flag=super.onOptionsItemSelected(item);  
  59.             break;  
  60.         }  
  61.         return flag;  
  62.     }  
  63.       

  實現效果,Android2.3:

   使用XML資源文件定義選項菜單,XML資源文件:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <menu xmlns:android="http://schemas.android.com/apk/res/android" > 
  3.  
  4.     <item 
  5.         android:id="@+id/item1" 
  6.         android:showAsAction="never" 
  7.         android:title="System menu"> 
  8.     </item> 
  9.     <item 
  10.         android:id="@+id/item2" 
  11.         android:showAsAction="never" 
  12.         android:title="User menu"   
  13.         android:icon="@drawable/ic_launcher"> 
  14.     </item> 
  15.     <item 
  16.         android:id="@+id/item3" 
  17.         android:showAsAction="never" 
  18.         android:title="Intent menu"   
  19.         android:icon="@drawable/ic_launcher"> 
  20.     </item> 
  21.     <group android:id="@+id/group_file" > 
  22.         <item android:id="@+id/menu_save"   
  23.               android:title="menu group save" /> 
  24.         <item android:id="@+id/menu_delete" 
  25.               android:title="menu group delete" /> 
  26.     </group> 
  27.     <item android:id="@+id/file" 
  28.           android:title="Sub menus" > 
  29.         <!-- "file" submenu --> 
  30.         <menu> 
  31.             <item android:id="@+id/sub_menu1" 
  32.                   android:title="Sub menu1" /> 
  33.             <item android:id="@+id/sub_menu21" 
  34.                   android:title="Sub menu2" /> 
  35.             <item android:id="@+id/sub_menu3" 
  36.                   android:title="Sub menu3" /> 
  37.         </menu> 
  38.     </item> 
  39. </menu> 

 Java代碼:

  1. package com.example.menudemo;  
  2.  
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.Menu;  
  7. import android.view.MenuItem;  
  8. import android.widget.TextView;  
  9. import android.widget.Toast;  
  10.  
  11. public class OptionMenu2Activitty extends Activity {  
  12.     private TextView  tv;  
  13.     @Override 
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         // TODO Auto-generated method stub  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_optionmenu1);  
  18.         tv=(TextView)findViewById(R.id.tvOptionMenu1);  
  19.         tv.setText("加載XML資源填充Menu");          
  20.     }  
  21.       
  22.     @Override 
  23.     public boolean onCreateOptionsMenu(Menu menu) {  
  24.         // 使用布局文件加載菜單  
  25.         getMenuInflater().inflate(R.menu.optionmenu2, menu);  
  26.         return super.onCreateOptionsMenu(menu);  
  27.     }  
  28.       
  29.     @Override 
  30.     public boolean onOptionsItemSelected(MenuItem item) {  
  31.  
  32.         switch (item.getItemId()) {  
  33.         case R.id.item1:  
  34.             Toast.makeText(OptionMenu2Activitty.this, "selected System menu", Toast.LENGTH_SHORT).show();  
  35.             return true;  
  36.         case R.id.item2:  
  37.             Toast.makeText(OptionMenu2Activitty.this, "selected User menu", Toast.LENGTH_SHORT).show();  
  38.             return true;  
  39.         case R.id.item3:  
  40.             Intent intent=new Intent(OptionMenu2Activitty.this, IntentActivity.class);  
  41.             startActivity(intent);  
  42.             return true;  
  43.         case R.id.menu_save:  
  44.             Toast.makeText(OptionMenu2Activitty.this, "file save", Toast.LENGTH_SHORT).show();  
  45.             return true;  
  46.         case R.id.sub_menu1:  
  47.             Toast.makeText(OptionMenu2Activitty.this, "Selected sub_menu1", Toast.LENGTH_SHORT).show();  
  48.             return true;  
  49.         default:  
  50.             return super.onOptionsItemSelected(item);  
  51.         }  
  52.           
  53.           
  54.     }  
  55.       

  效果和使用Java代碼聲明菜單一樣,這裡就不再展示了。

ContextMenu

  ContextMenu,上下文菜單提供了注冊在View組件的菜單操作,它以一個浮動的窗口顯示(類似於對話框),當用戶長按某被注冊了上下文菜單的視圖,則觸發上下文菜單顯示。通常都用於ListView或者GridView等視圖集合中。

  使用上下文菜單的步驟:

  1. 使用Activity.registerForContextMenu(View)方法為指定View注冊上下文菜單。
  2. 在Activity或者Fragment中重寫onCreateContextMenu()方法,當被注冊的視圖接受到長按事件後,系統調用onCreateContextMenu()方法,在這個方法中聲明上下文菜單。
  3. 實現onContextItemSelected()方法,用於響應菜單想的選中。

  示例,菜單XML資源文件代碼:

  1. <menu xmlns:android="http://schemas.android.com/apk/res/android" > 
  2.  
  3.      <item 
  4.         android:id="@+id/context_copy" 
  5.         android:orderInCategory="100" 
  6.         android:showAsAction="never" 
  7.         android:title="Copy"/> 
  8.     <item 
  9.         android:id="@+id/context_edit" 
  10.         android:orderInCategory="100" 
  11.         android:showAsAction="never" 
  12.         android:title="Edit"/> 
  13.     <item 
  14.         android:id="@+id/context_delete" 
  15.         android:orderInCategory="100" 
  16.         android:showAsAction="never" 
  17.         android:title="Delete"/> 
  18. </menu> 

  Java代碼:

  1. package com.example.menudemo;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.  
  6. import android.app.Activity;  
  7. import android.os.Bundle;  
  8. import android.view.ContextMenu;  
  9. import android.view.MenuInflater;  
  10. import android.view.MenuItem;  
  11. import android.view.View;  
  12. import android.view.ContextMenu.ContextMenuInfo;  
  13. import android.widget.AdapterView.AdapterContextMenuInfo;  
  14. import android.widget.ArrayAdapter;  
  15. import android.widget.ListView;  
  16. import android.widget.Toast;  
  17.  
  18. public class ContextMenu1 extends Activity {  
  19.     private ListView listview;  
  20.     private List<String> dataList;  
  21.     @Override 
  22.     protected void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.activity_contextmenu1);  
  25.         listview=(ListView)findViewById(R.id.listView1);  
  26.         dataList=getData();  
  27.         ArrayAdapter<String> adapter=new  ArrayAdapter<String>(ContextMenu1.this,android.R.layout.simple_list_item_1, dataList);  
  28.         listview.setAdapter(adapter);  
  29.         //為ListView注冊上下文菜單  
  30.         registerForContextMenu(listview);  
  31.     }  
  32.       
  33.     @Override 
  34.     public void onCreateContextMenu(ContextMenu menu, View v,  
  35.             ContextMenuInfo menuInfo) {  
  36.         super.onCreateContextMenu(menu, v, menuInfo);  
  37.         //填充一個XML菜單文件  
  38.         MenuInflater inflater = getMenuInflater();  
  39.         inflater.inflate(R.menu.contextmenu, menu);  
  40.     }  
  41.       
  42.     @Override 
  43.     public boolean onContextItemSelected(MenuItem item) {  
  44.         //獲取上下文菜單綁定的AdapterView的額外信息  
  45.         AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();  
  46.         switch (item.getItemId()) {  
  47.         case R.id.context_copy:  
  48.             Toast.makeText(ContextMenu1.this, "copy "+dataList.get(info.position), Toast.LENGTH_SHORT).show();  
  49.             return true;  
  50.         case R.id.context_delete:  
  51.             Toast.makeText(ContextMenu1.this, "delete "+dataList.get(info.position), Toast.LENGTH_SHORT).show();  
  52.             return true;  
  53.         case R.id.context_edit:  
  54.             Toast.makeText(ContextMenu1.this, "edit " +dataList.get(info.position), Toast.LENGTH_SHORT).show();  
  55.             return true;  
  56.         default:  
  57.             return super.onContextItemSelected(item);  
  58.         }          
  59.     }  
  60.     //ListView數據  
  61.     public List<String> getData()  
  62.     {          
  63.         List<String> data=new ArrayList<String>();  
  64.         for(int i=0;i<8;i++)  
  65.         {  
  66.             data.add("item"+i);  
  67.         }  
  68.         return data;  
  69.     }      

  效果展示,Android4.0:

ActionMode

  ActionMode,是一個系統實現的用戶交互,當用戶使用ActionMode後,選擇一個選項,一個上下文操作欄會出現在屏幕的頂端,呈現出用戶可以對當前選中項目進行的操作選項。進入這種狀態可以通過後退按鈕或者調用finish()退出。ActionMode為Android3.0之後的支持,所以在開發3.0之後的應用,推薦使用ActionMode,而不是ContextMenu。

  使用ActionMode的步驟:

  1. 實現ActionMode.Callback接口。在它的回調方法中,可以設置操作的上下文操作欄。
  2. 在需要顯示上下文操作欄的時候,調用startActionMode(ActionMode.Callback)。

  ActionMode.Callback是ActionMode定義的一個內部接口,這個接口需要實現下面四個方法:

  • boolean onCreateActionMode(ActionMode mode,Menu menu):第一次被創建的時候調用。
  • boolean onPrepareActionMode(ActionMode mode,Menu menu):刷新菜單列表的時候被調用,一般使用false即可。
  • boolean onActionItemClicked(ActionMode mode,MenuItem item):菜單項被選中的時候被調用。
  • void onDestroyActionMode(ActionMode mode):退出或銷毀的時候被調用。

  示例:

 

  1. package com.example.menudemo;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.  
  6. import android.annotation.SuppressLint;  
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.view.ActionMode;  
  10. import android.view.ActionMode.Callback;  
  11. import android.view.Menu;  
  12. import android.view.MenuInflater;  
  13. import android.view.MenuItem;  
  14. import android.view.View;  
  15. import android.widget.AdapterView;  
  16. import android.widget.AdapterView.AdapterContextMenuInfo;  
  17. import android.widget.AdapterView.OnItemLongClickListener;  
  18. import android.widget.ArrayAdapter;  
  19. import android.widget.ListView;  
  20. import android.widget.Toast;  
  21.  
  22. public class ActionModeMenu1 extends Activity {  
  23.     private ListView listview;  
  24.     private List<String> dataList;  
  25.     private ActionMode mActionMode;  
  26.     @Override 
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         // TODO Auto-generated method stub  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_contextmenu1);  
  31.         listview=(ListView)findViewById(R.id.listView1);  
  32.         dataList=getData();  
  33.         ArrayAdapter<String> adapter=new  ArrayAdapter<String>(ActionModeMenu1.this,android.R.layout.simple_list_item_1, dataList);  
  34.         listview.setAdapter(adapter);  
  35.         listview.setOnItemLongClickListener(new OnItemLongClickListener() {  
  36.             @SuppressLint("NewApi")  
  37.             @Override 
  38.             public boolean onItemLongClick(AdapterView<?> parent, View view,  
  39.                     int position, long id) {          
  40.                 if (mActionMode != null) {  
  41.                     return false;  
  42.                 }  
  43.                 //顯示ActionMode  
  44.                 mActionMode = startActionMode(mActionModeCallback);  
  45.                 //標記選中項的下表  
  46.                 mActionMode.setTag(position);  
  47.                 //標記ListView為可選狀態  
  48.                 view.setSelected(true);  
  49.                 return true;  
  50.             }  
  51.         });  
  52.     }  
  53.     public List<String> getData()  
  54.     {  
  55.         List<String> data=new ArrayList<String>();  
  56.         for(int i=0;i<8;i++)  
  57.         {  
  58.             data.add("item"+i);  
  59.         }  
  60.         return data;  
  61.     }  
  62.       
  63.     private ActionMode.Callback mActionModeCallback=new Callback() {  
  64.           
  65.         @Override 
  66.         public boolean onPrepareActionMode(ActionMode mode, Menu menu) {  
  67.             //刷新菜單列表的時候被調用,但是一般無需刷新  
  68.             return false;  
  69.         }  
  70.           
  71.         @Override 
  72.         public void onDestroyActionMode(ActionMode mode) {  
  73.             //銷毀ActionMode  
  74.             mActionMode = null;  
  75.         }  
  76.           
  77.         @Override 
  78.         public boolean onCreateActionMode(ActionMode mode, Menu menu) {  
  79.             //創建ActionMode  
  80.             //使用資源文件填充  
  81.             MenuInflater inflater = mode.getMenuInflater();  
  82.             inflater.inflate(R.menu.contextmenu, menu);  
  83.             return true;  
  84.         }  
  85.  
  86.         @Override 
  87.         public boolean onActionItemClicked(ActionMode mode, MenuItem item) {  
  88.             //獲取選項中下表  
  89.             int position=(Integer)mode.getTag();  
  90.             switch (item.getItemId()) {  
  91.             case R.id.context_copy:  
  92.                 Toast.makeText(ActionModeMenu1.this, "copy "+dataList.get(position), Toast.LENGTH_SHORT).show();  
  93.                 //finish退出ActionMode模式  
  94.                 mode.finish();  
  95.                 return true;  
  96.             case R.id.context_delete:  
  97.                 Toast.makeText(ActionModeMenu1.this, "delete "+dataList.get(position), Toast.LENGTH_SHORT).show();  
  98.                 mode.finish();  
  99.                 return true;  
  100.             case R.id.context_edit:  
  101.                 Toast.makeText(ActionModeMenu1.this, "edit " +dataList.get(position), Toast.LENGTH_SHORT).show();  
  102.                 mode.finish();  
  103.                 return true;  
  104.             default:  
  105.                 return false;  
  106.         }  
  107.         }  
  108.     };  
  109.       
  110.       

 效果展示,Android4.0:

 

PopupMenu

  PopupMenu,彈出菜單,一個模態形式展示的彈出風格的菜單,綁在在某個View上,一般出現在被綁定的View的下方(如果下方有空間)。

  使用PopupMenu的步驟:

  1. 通過PopupMenu的構造函數實例化一個PopupMenu對象,需要傳遞一個當前上下文對象以及綁定的View。
  2. 調用PopupMenu.setOnMenuItemClickListener()設置一個PopupMenu選項的選中事件。
  3. 使用MenuInflater.inflate()方法加載一個XML文件到PopupMenu.getMenu()中。
  4. 在需要的時候調用PopupMenu.show()方法顯示。

  示例:

  1. public void showPopup(View v){  
  2.         PopupMenu popup=new PopupMenu(MainActivity.this, v);  
  3.         popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {  
  4.               
  5.             @Override 
  6.             public boolean onMenuItemClick(MenuItem item) {  
  7.                 switch (item.getItemId()) {  
  8.                 case R.id.context_copy:  
  9.                     Toast.makeText(MainActivity.this, "select copy ", Toast.LENGTH_SHORT).show();  
  10.                     return true;  
  11.                 case R.id.context_delete:  
  12.                     Toast.makeText(MainActivity.this, " select delete ", Toast.LENGTH_SHORT).show();  
  13.                     return true;  
  14.                 case R.id.context_edit:  
  15.                     Toast.makeText(MainActivity.this, " select edit ", Toast.LENGTH_SHORT).show();  
  16.                     return true;  
  17.                     default :  
  18.                     return false;  
  19.                 }  
  20.             }  
  21.         });  
  22.         popup.getMenuInflater().inflate(R.menu.contextmenu,popup.getMenu());  
  23.         popup.show();  
  24.     } 

 效果展示,Android4.0:

  源碼下載

總結

  以上就講解了Android下Menu的使用。因為上面的所有示例均在一個項目中完成的,所以有些低版本的操作,需要更改AndroidManifest.xml文件中的最低支持版本,改到8即可。在現在的實際開發中,最好還是使用對高版本只是的ActionBar、ActionMode、PopupMenu比較好。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved