創建菜單 Creating Menus
菜單是任何應用程序的一個重要部分,提供了透露應用程序功能和設置的通用接口。 Android 為開發者提供了一個簡單的編程接口來實現各種條件下的標準化應用程序菜單。
Android 提供了三種基礎菜單類型:
選項菜單 Options Menu
這是一個活動的主菜單。通過按下設備菜單鍵來顯示它。選項菜單包含兩組菜單項:
圖標菜單 Icon Menu
這個是當用戶按下菜單鍵時最初出現屏幕下方的 item 集合。它支持最多 6 個菜單項。只有這些菜單支持圖標而且這些菜單并不支持 checkboxes 或者 radio buttons 。
擴展菜單 Expanded Menu
這是通過按“更多”菜單顯現出來的一個豎向的項目列表。它僅當圖標菜單過多時存在而且是由 6 個以及其它選項菜單組成。
上下文菜單 Context Menu
這是一個浮動菜單列表,通常在你長時間按在一個視圖上時出現(比如一個列表項)
子菜單 Submenu
這是一個浮動菜單列表,通過在選項菜單或上下文菜單選擇菜單項顯露出來。不支持嵌套子菜單。
選項菜單 Options Menu
這個選項菜單通過按設備菜單鍵打開。打開后,出現圖標菜單,可包含 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 中的相關主題。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
