創(chuàng)建菜單 Creating Menus
菜單是任何應(yīng)用程序的一個(gè)重要部分,提供了透露應(yīng)用程序功能和設(shè)置的通用接口。 Android 為開發(fā)者提供了一個(gè)簡(jiǎn)單的編程接口來實(shí)現(xiàn)各種條件下的標(biāo)準(zhǔn)化應(yīng)用程序菜單。
Android 提供了三種基礎(chǔ)菜單類型:
選項(xiàng)菜單 Options Menu
這是一個(gè)活動(dòng)的主菜單。通過按下設(shè)備菜單鍵來顯示它。選項(xiàng)菜單包含兩組菜單項(xiàng):
圖標(biāo)菜單 Icon Menu
這個(gè)是當(dāng)用戶按下菜單鍵時(shí)最初出現(xiàn)屏幕下方的 item 集合。它支持最多 6 個(gè)菜單項(xiàng)。只有這些菜單支持圖標(biāo)而且這些菜單并不支持 checkboxes 或者 radio buttons 。
擴(kuò)展菜單 Expanded Menu
這是通過按“更多”菜單顯現(xiàn)出來的一個(gè)豎向的項(xiàng)目列表。它僅當(dāng)圖標(biāo)菜單過多時(shí)存在而且是由 6 個(gè)以及其它選項(xiàng)菜單組成。
上下文菜單 Context Menu
這是一個(gè)浮動(dòng)菜單列表,通常在你長(zhǎng)時(shí)間按在一個(gè)視圖上時(shí)出現(xiàn)(比如一個(gè)列表項(xiàng))
子菜單 Submenu
這是一個(gè)浮動(dòng)菜單列表,通過在選項(xiàng)菜單或上下文菜單選擇菜單項(xiàng)顯露出來。不支持嵌套子菜單。
選項(xiàng)菜單 Options Menu
這個(gè)選項(xiàng)菜單通過按設(shè)備菜單鍵打開。打開后,出現(xiàn)圖標(biāo)菜單,可包含 6 個(gè)菜單項(xiàng)。如果添加多于 6 個(gè)菜單項(xiàng),多出的部分將通過“更多”菜單項(xiàng)在擴(kuò)展菜單中顯示。擴(kuò)展菜單項(xiàng)在多于 6 個(gè)菜單項(xiàng)時(shí)自動(dòng)添加。
選項(xiàng)菜單應(yīng)該包含應(yīng)用程序的基本功能以及任何必要的瀏覽項(xiàng)(例如,返回桌面或應(yīng)用程序設(shè)置)。你還可以通過增加子菜單 Submenus 來組織主題和包含額外的菜單功能。
當(dāng)菜單第一次被打開時(shí),系統(tǒng)會(huì)調(diào)用活動(dòng) onCreateOptionsMenu() 回調(diào)函數(shù)。重寫該方法并生成傳遞給你的這個(gè)菜單對(duì)象。你可以通過擴(kuò)充定義在 XML 文件中的一個(gè)菜單資源或者通過為你想要的每一個(gè)菜單項(xiàng)調(diào)用 add() 方法生成這個(gè)菜單。這個(gè)方法增加一個(gè)菜單項(xiàng) MenuItem ,并返回新創(chuàng)建的對(duì)象。你可以用返回的 MenuItem 來設(shè)置附加屬性如圖標(biāo),快捷鍵,意圖以及這個(gè)菜單項(xiàng)的其它設(shè)置。
有多個(gè) add() 方法。通常,你會(huì)使用接受一個(gè) itemId 參數(shù)的那個(gè)。這是一個(gè)唯一的整數(shù),允許你在回調(diào)函數(shù)中識(shí)別這個(gè) item 。
當(dāng)一個(gè)菜單項(xiàng)從選項(xiàng)菜單中被選擇時(shí),你會(huì)接收到一個(gè)
onOptionsItemSelected()
回調(diào)。這個(gè)回調(diào)傳給你選中的
MenuItem
。
你可以通過請(qǐng)求
itemId
:
getItemId()
來識(shí)別它,這將返回
add()
方法分配的整數(shù)。一旦你識(shí)別了這個(gè)菜單項(xiàng),就可以采取合適的動(dòng)作。
下面是一個(gè)活動(dòng)里的例子,其中我們創(chuàng)建了一個(gè)選項(xiàng)菜單并處理菜單項(xiàng)的選擇:
/* 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;
}
這個(gè)
add()
方法有四個(gè)參數(shù):
groupId
,
itemId
,
order
,
和
title
。
groupId
允許你關(guān)聯(lián)這個(gè)菜單到一個(gè)菜單組中(更多參見下面的菜單組
Menu groups
)
-
這個(gè)例中,我們忽略掉它。
itemId
是用來識(shí)別菜單項(xiàng)的唯一的整數(shù),在回調(diào)函數(shù)中使用。
order
允許我們定義菜單的顯示順序
-
缺省情況下,它們以添加時(shí)的順序排列。
title
當(dāng)然是菜單的名字(可以是一個(gè)字符串資源,為了本地化更加方便,建議你使用資源)。
提示 : 如果你有一些可以以一個(gè)標(biāo)題歸類的菜單項(xiàng),考慮以子菜單 Submenu 的方式組織它們。
增加圖標(biāo) Adding icons
圖標(biāo)也可以通過 setIcon() 函數(shù)被添加到菜單項(xiàng)中。
menu.add(0, MENU_QUIT, 0, "Quit")
.setIcon(R.drawable.menu_quit_icon);
修改菜單 Modifying the menu
如果有些時(shí)候你想在選項(xiàng)菜單被打開的時(shí)候 re-write 它,可以 override onPrepareOptionsMenu() 方法,該方法在每一次菜單被打開的時(shí)候調(diào)用。它將傳遞給你菜單對(duì)象,就像回調(diào)一樣。這對(duì)于根據(jù)應(yīng)用程序狀態(tài)調(diào)整菜單選項(xiàng)很有用。
注意 : 當(dāng)改變菜單項(xiàng)時(shí),根據(jù)當(dāng)前選擇的 item 來這樣做是一個(gè)不好的行為。記住,在觸摸模式中,將不會(huì)有一個(gè)選擇或聚焦的 item 。相反,當(dāng)你想基于 UI 中的某個(gè)特定 item 來提供功能時(shí),你應(yīng)該使用一個(gè) Context Menu 來完成這種行為。
上下文菜單 Context Menu
Android 的上下文菜單在概念上和 PC 軟件的右鍵菜單類似。當(dāng)一個(gè)視圖注冊(cè)到一個(gè)上下文菜單時(shí),執(zhí)行一個(gè)在該對(duì)象上的“長(zhǎng)按”(按住不動(dòng)差不多兩秒鐘)動(dòng)作,將出現(xiàn)一個(gè)提供相關(guān)功能的浮動(dòng)菜單。上下文菜單可以被注冊(cè)到任何視圖對(duì)象中,不過,最常見的是用于列表視圖 ListView 的 item ,在按中列表項(xiàng)時(shí),會(huì)轉(zhuǎn)換其背景色而提示將呈現(xiàn)上下文菜單。 (電話聯(lián)系人列表提供了關(guān)于這個(gè)特性的一個(gè)很好的例子)。
注意:上下文菜單項(xiàng)不支持圖標(biāo)或快捷鍵。
為了創(chuàng)建一個(gè)上下文菜單,你必須重寫這個(gè)活動(dòng)的上下文菜單回調(diào)函數(shù):
onCreateContextMenu()
和
onContextItemSelected()
。在回調(diào)函數(shù)
onCreateContextMenu()
里,你可以通過使用一個(gè)
add()
方法來添加菜單項(xiàng),或者通過擴(kuò)充一個(gè)定義在
XML
中的菜單資源。然后,通過
registerForContextMenu()
為這個(gè)視圖注冊(cè)一個(gè)上下文菜單
ContextMenu
.
比如,下面的代碼可以被用到 Notepad 應(yīng)用程序中來為列表中的每一個(gè)注釋添加一個(gè)上下文菜單:
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
外,還需要給定選中的視圖和一個(gè)上下文菜單信息
ContextMenuInfo
對(duì)象,該對(duì)象提供了選中對(duì)象的附加信息。在本例中,
onCreateContextMenu()
沒做什么特別的事
-
只是添加了一些菜單項(xiàng)。在
onContextItemSelected()
回調(diào)函數(shù)中,我們從
MenuItem
中請(qǐng)求
AdapterContextMenuInfo
,該對(duì)象提供當(dāng)前選中項(xiàng)的信息。我們從中所要的只是這個(gè)選中項(xiàng)的列表
ID
,所以無論編輯還是刪除一個(gè)注釋,我們通過這個(gè)對(duì)象的
AdapterContextMenuInfo.info
字段來找到該
ID
。這個(gè)
ID
被傳遞給
editNote()
和
deleteNote()
方法來執(zhí)行相應(yīng)的動(dòng)作。
現(xiàn)在,要為一個(gè)列表視圖中的所有項(xiàng)注冊(cè)上下文菜單,我們可以傳遞整個(gè)的列表視圖對(duì)象給 registerForContextMenu(View) 方法:
registerForContextMenu(getListView());
記住,你可以傳遞任何視圖對(duì)象來注冊(cè)一個(gè)上下文菜單。這里, getListView() 返回這個(gè)被用于 Notepad 應(yīng)用程序的列表活動(dòng) ListActivity 中的列表視圖對(duì)象。這樣,這個(gè)列表中的任何 item 都被注冊(cè)到這個(gè)上下文菜單。
子菜單 Submenus
一個(gè)子菜單可以被添加進(jìn)任何菜單中,但不能加入另外的子菜單中。當(dāng)你的應(yīng)用程序有很多功能可以按主題組織的時(shí)候,這將非常有用,就好比 PC 應(yīng)用程序的菜單欄(文件,編輯,視圖,等)。
子菜單通過 addSubMenu() 加入到已有的菜單中而創(chuàng)建。該函數(shù)會(huì)返回一個(gè)子菜單 SubMenu 對(duì)象(菜單 Menu 的一個(gè)擴(kuò)展)。然后你可以通過調(diào)用 add() 方法給這個(gè)菜單添加其他項(xiàng),例如:
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;
}
子菜單中選擇項(xiàng)的回調(diào)動(dòng)作將由父菜單的回調(diào)方法處理。比如上面的例子,子菜單中的選擇將由
onOptionsItemSelected()
回調(diào)處理。
你也可以在 XML 中定義父菜單時(shí)增加子菜單。
在 XML 里定義菜單 Define Menus in XML
就像
Android
用戶界面布局一樣,你可以在
XML
文件中定義菜單,然后在你菜單的
onCreate...()
回調(diào)函數(shù)中擴(kuò)充它們。這使得你的應(yīng)用程序代碼簡(jiǎn)潔而且把更多的界面設(shè)計(jì)分離到
XML
文件中,這更容易形象化。
首先,在你的工程
res/
的目錄下創(chuàng)建一個(gè)新的目錄叫
menu
。你所有定義應(yīng)用程序菜單的
XML
文件都應(yīng)該放在這里。
在一個(gè)菜單
XML
布局中,有三個(gè)合法的元素:
<menu>
,
<group>
和
<item>
。
item
和
group
必須是菜單的子元素,而
item
元素還可以是
group
的子元素,并且另外一個(gè)菜單元素可以是一個(gè)
item
的子元素(來創(chuàng)建一個(gè)子菜單)。當(dāng)然,任何文件的根元素必須是一個(gè)
menu
元素。
作為一個(gè)例子,我們將定義和在上面的選項(xiàng)菜單
Options Menu
章節(jié)中所創(chuàng)建的相同的菜單,我們首先在目錄
res/menu/
里創(chuàng)建一個(gè)名為
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()
方法擴(kuò)充這個(gè)資源:
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
getMenuInflater() 方法返回我們活動(dòng)上下文的 MenuInflater 。 然后我們調(diào)用 inflate() ,傳遞給它一個(gè)指向我們菜單資源的指針以及回調(diào)給出的菜單對(duì)象。
盡管和在
onCreateOptionsMenu()
創(chuàng)建菜單比較起來,上面的例子看起來做了更多的事情,但是如果處理更多的菜單項(xiàng),這將省掉很多麻煩并讓你的代碼簡(jiǎn)潔。
你可以通過把
item
元素打包進(jìn)一個(gè)
group
中來定義菜單組
menu groups
,然后通過在一個(gè)
item
中嵌入另外一個(gè)
menu
來創(chuàng)建子菜單。每個(gè)元素都支持必需的屬性來控制快捷鍵,復(fù)選框,圖標(biāo),以及更多特性。
要了解這些屬性和更多的 XML 語法,請(qǐng)參見可用資源類型 Available Resource Types 中的相關(guān)主題。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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