- Android 5從入門到精通
- 李波
- 1901字
- 2021-03-19 15:29:03
4.5 Menu和ActionBar
菜單是人機交互的重要接口,在Android SDK中,提供了菜單類android.view.Menu,以完成與菜單有關的操作。
Android SDK提供三種菜單,分別為:
●Options Menu:又稱選項菜單,是Activity的主要菜單項的集合,當用戶單擊Menu按鈕時出現。在Android 2.3以下的版本中,這種菜單最多顯示六個帶圖標的菜單項。當菜單中含有六個以上的菜單項時,彈出菜單將只顯示前五個菜單,第六個菜單項會變為More,單擊More菜單項后會出現擴展菜單。擴展菜單不支持圖標,但支持單選框和復選框。在Android 3.0(API Level 11)及其以上版本中,默認情況下直接彈出的選項菜單不再顯示圖標。
●Context Menu:又稱上下文菜單,是一個懸浮的菜單項列表,當用戶單擊注冊了上下文菜單的組件時出現。上下文菜單不支持菜單圖標和快捷鍵。
●Submenu:又稱子菜單,是某個菜單項的擴展,是一個懸浮的菜單項列表。子菜單不支持菜單圖標或者嵌套子菜單。
4.5.1 Options Menu
要實現選項菜單的功能,首先需要重載OnCreatOptionsMenu()方法創建菜單,然后通過onOptionsItemSelected()方法對菜單被單擊事件進行監聽和處理。
創建一個名為MenusDemo的Eclipse Android Project,在該工程中對菜單的相關知識進行學習。
在工程的res目錄下創建一個menu目錄,用于存放菜單相關的xml文件。在該目錄下創建mymenu.xml,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/item1" android:title="@string/menuitem1" android:icon="@drawable/icon01"/> <item android:id="@+id/item2" android:title="@string/menuitem2" android:icon="@drawable/icon02"/> <item android:id="@+id/item3" android:title="@string/menuitem3" android:icon="@drawable/icon03"/> <item android:id="@+id/item4" android:title="@string/menuitem4" android:icon="@drawable/icon04"/> <item android:id="@+id/item5" android:title="@string/menuitem5" android:icon="@drawable/icon05"/> <item android:id="@+id/item6" android:title="@string/menuitem6" android:icon="@drawable/icon06"/> <item android:id="@+id/item7" android:title="@string/menuitem7" android:icon="@drawable/icon07"/> </menu>
mymenu.xml創建了一個具有七個菜單項的菜單,并且通過android:id屬性為每個菜單項指定了id,通過android:title屬性為每個菜單項指定了顯示的菜單項內容,通過android:icon屬性指定了每個菜單項的圖標。對應的圖標文件放置到res/drawable目錄下。
為工程MenusDemo創建名為MenusActivity的Activity,將mymenu.xml中定義的菜單設置為MenusActivity的菜單,重載OnCreatOptionsMenu()方法。MenusActivity.java代碼如下:
package introduction.android.menusDemo; import android.app.ActionBar; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.TextView; public class MenusDemoActivity extends Activity { private TextView textview; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); textview=(TextView)findViewById(R.id.textview1); } @Override public boolean onOptionsItemSelected(MenuItem item){ // TODO Auto-generated method stub switch(item.getItemId()){ case R.id.item1: textview.setText("item1 selected!"); break; case R.id.item2: textview.setText("item2 selected!"); break; case R.id.item3: textview.setText("item3 selected!"); break; default: break; } return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu){ MenuInflater inflater=getMenuInflater(); inflater.inflate(R.menu.mymenu, menu); return true; } }
其中,
public boolean onCreateOptionsMenu(Menu menu){ MenuInflater inflater=getMenuInflater(); inflater.inflate(R.menu.mymenu, menu); return true; }
這幾行代碼通過MenuInflater. Inflate()方法將menu.xml中的定義的菜單項內容填充到了菜單中。
在OnCreatOptionsMenu()方法中創建菜單時也支持Menu.add()方法,也能達到同樣目的。例如:
menu.add(0,itemid,0,item_title);
表示在菜單中添加一個菜單項,該菜單項的id為itemid,菜單項顯示的內容為item_title的內容。但是不鼓勵使用這種方式,而應該使用xml文件來創建菜單。
運行MenusDemo實例,單擊手機的Menu按鈕,得到運行效果如圖4.35所示。

圖4.35 “Menu”按鈕運行效果
由運行效果可見,MenusActivity已經根據mymenu.xml文件創建了一個具有七個菜單項的菜單。但是雖然在mymenu.xml文件中為每個菜單項指定了一個圖標,但是生成的選項菜單中卻并沒有圖標被顯示出來,這是為什么呢?
實例MenusDemo當前的運行環境是Android4.0,其API Level為14。我們先看一下,同樣的代碼,在API Level 11之前的運行效果。
雙擊打開AndroidManifest.xml文件,將其中的代碼:
<uses-sdk android:minSdkVersion="14" />
改為:
<uses-sdk android:minSdkVersion="9" />
再次運行MenusDemo實例,單擊Menu按鈕,得到運行效果如圖4.36所示。

圖4.36 API Level 11之前Menu按鈕運行效果
可見運行在早期的API之上的選項菜單效果要更好一些。為什么會出現這種現象呢?其實在Android SDK 3.0之后,就不再鼓勵直接使用選項菜單,而是將選項菜單和ActionBar結合使用。
ActionBar又稱活動欄,位于Activity的頂部,取代了原來的標題的位置。ActionBar中包含很多ActionItem,相當于選項菜單的菜單項。將選項菜單與ActionBar結合的方法很簡單,只要在xml文件中添加一個android:showAsAction="ifRoom"屬性即可。該屬性表現如果標題欄有空間的話,就將相關的菜單項放置到ActionBar中。如果標題欄空間不足,未能放置到其中的菜單項仍然會以選項菜單的形式出現。

圖4.37 ActionBar運行效果
4.5.2 Context Menu
上下文菜單注冊到View對象上后,用戶長按該View對象可呼出上下文菜單。上下文菜單懸浮于主界面之上,不支持圖標顯示和快捷鍵。其使用方法和選項菜單高度相似,只不過創建上下文菜單的方法為onCreateContextMenu(),響應上下文菜單單擊事件的方法為onContextItemSelected()。
仍以工程MenusDemo為例,為MenusActivity的視圖中的TextView對象添加一個具有兩個菜單項的上下文菜單,運行效果如圖4.38所示。

圖4.38 兩個上下文菜單的運行結果
為TextView對象注冊上下文菜單的代碼如下:
textview=(TextView)findViewById(R.id.textview1); registerForContextMenu(textview);
創建并處理上下文菜單單擊事件的代碼如下:
public boolean onContextItemSelected(MenuItem item){ // TODO Auto-generated method stub switch(item.getItemId()){ case R.id.item6: Log.i("menu","item6!"); break; case R.id.item7: Log.i("menu","item7!"); break; default: break; } return super.onContextItemSelected(item); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ // TODO Auto-generated method stub menu.add(0, R.id.item6, 0, "上下文菜單項一"); menu.add(0, R.id.item7, 0, "上下文菜單項二"); super.onCreateContextMenu(menu, v, menuInfo); }
4.5.3 SubMenu
子菜單可以被添加到其他菜單上,但是子菜單本身不能再有子菜單。使用addSubMenu()方法為MenusActivity的選項菜單添加一個子菜單,運行效果如圖4.39所示。

圖4.39 添加子菜單的運行效果
實現該子菜單需要重寫onCreateOptionsMenu()方法,代碼如下:
public boolean onCreateOptionsMenu(Menu menu){ MenuInflater inflater=getMenuInflater(); inflater.inflate(R.menu.mymenu, menu); SubMenu submenu=menu.addSubMenu("子菜單"); submenu.add(0,1,0,"子菜單項一"); submenu.add(0, 2, 0, "子菜單項二"); return true; }
子菜單的事件處理代碼在onOptionsItemSelected()中實現。
MenusActivity.java完整代碼如下:
package introduction.android.menusDemo; import android.app.ActionBar; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.SubMenu; import android.view.View; import android.widget.TextView; public class MenusDemoActivity extends Activity { private TextView textview; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); textview=(TextView)findViewById(R.id.textview1); registerForContextMenu(textview); // setContentView(textview); } @Override public boolean onOptionsItemSelected(MenuItem item){ // TODO Auto-generated method stub switch(item.getItemId()){ case 1: Log.i("menu","submenu item 1 selected"); case R.id.item1: textview.setText("item1 selected!"); break; case R.id.item2: textview.setText("item2 selected!"); break; case R.id.item3: textview.setText("item3 selected!"); break; default: Log.i("menu","other items selected"); break; } return super.onOptionsItemSelected(item); } @Override public boolean onCreateOptionsMenu(Menu menu){ MenuInflater inflater=getMenuInflater(); inflater.inflate(R.menu.mymenu, menu); SubMenu submenu=menu.addSubMenu("子菜單"); submenu.setIcon(android.R.drawable.ic_menu_crop); submenu.add(0,1,0,"子菜單項一"); submenu.add(0, 2, 0, "子菜單項二"); return true; } @Override public boolean onContextItemSelected(MenuItem item){ // TODO Auto-generated method stub switch(item.getItemId()){ case R.id.item6: Log.i("menu","item6!"); break; case R.id.item7: Log.i("menu","item7!"); break; default: break; } return super.onContextItemSelected(item); } @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ // TODO Auto-generated method stub menu.add(0, R.id.item6, 0, "上下文菜單項一"); menu.add(0, R.id.item7, 0, "上下文菜單項二"); super.onCreateContextMenu(menu, v, menuInfo); } }
- Mastering Visual Studio 2017
- Learn TypeScript 3 by Building Web Applications
- C#程序設計實訓指導書
- 零基礎學Scratch少兒編程:小學課本中的Scratch創意編程
- Java從入門到精通(第5版)
- 精通Python設計模式(第2版)
- Learning DHTMLX Suite UI
- Python忍者秘籍
- Web Development with MongoDB and Node(Third Edition)
- 領域驅動設計:軟件核心復雜性應對之道(修訂版)
- Linux Shell核心編程指南
- Learning Continuous Integration with TeamCity
- Creating Data Stories with Tableau Public
- Scala編程(第5版)
- R語言:邁向大數據之路(加強版)