android用户界面-菜单
創(chuàng)建菜單 Creating Menus?
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)的選擇:
Java代碼??
/*?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è)標(biāo)題歸類的菜單項(xiàng),考慮以子菜單Submenu的方式組織它們。
增加圖標(biāo)Adding icons
圖標(biāo)也可以通過setIcon()函數(shù)被添加到菜單項(xiàng)中。
Java代碼修改菜單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 來完成這種行為。
實(shí)例:
/Chapter04_UI_Menu01/src/com/amaker/test/MainActivity.java
代碼 package com.amaker.test;import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
/**
*
* 選項(xiàng)菜單實(shí)例
*/
public class MainActivity extends Activity {
private static final int ITEM1 = Menu.FIRST;
private static final int ITEM2 = Menu.FIRST+1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/**
* 覆蓋該方法添加菜單項(xiàng)
*/
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, ITEM1, 0, "開始");
menu.add(0, ITEM2, 0, "退出");
return true;
}
/**
* 覆蓋該方法,響應(yīng)菜單選項(xiàng)被單擊事件
*/
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case ITEM1:
setTitle("開始游戲!");
break;
case ITEM2:
setTitle("退出!");
break;
}
return true;
}
}
?
?
?
?
上下文菜單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è)上下文菜單:
Java代碼public?void?onCreateContextMen(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) 方法:
Java代碼記住,你可以傳遞任何視圖對(duì)象來注冊(cè)一個(gè)上下文菜單。這里,getListView()返回這個(gè)被用于Notepad應(yīng)用程序的列表活動(dòng)ListActivity中的列表視圖對(duì)象。這樣,這個(gè)列表中的任何item都被注冊(cè)到這個(gè)上下文菜單。
?
代碼 package com.amaker.test;import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.TextView;
/**
*
* @author 測(cè)試上下文菜單,改變背景色
*/
public class MainActivity extends Activity {
private static final int ITME1 = Menu.FIRST;
private static final int ITME2 = Menu.FIRST+1;
private static final int ITME3 = Menu.FIRST+2;
private TextView myTV;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myTV = (TextView)findViewById(R.id.TextView01);
registerForContextMenu(myTV);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(0, ITME1, 0, "紅色背景");
menu.add(0, ITME2, 0, "綠色背景");
menu.add(0, ITME3, 0, "白色背景");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case ITME1:
myTV.setBackgroundColor(Color.RED);
break;
case ITME2:
myTV.setBackgroundColor(Color.GREEN);
break;
case ITME3:
myTV.setBackgroundColor(Color.WHITE);
break;
}
return true;
}
}
?
?
?
子菜單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),例如:
Java代碼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 的文件。
Java代碼<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è)資源:
Java代碼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),以及更多特性。
代碼 package com.amaker.test;import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
/**
*
* 選項(xiàng)菜單實(shí)例
*/
public class MainActivity extends Activity {
private static final int ITEM1 = Menu.FIRST;
private static final int ITEM2 = Menu.FIRST+1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/**
* 覆蓋該方法添加子菜單項(xiàng)
*/
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu file = menu.addSubMenu("文件");
SubMenu edit = menu.addSubMenu("編輯");
file.add(0, ITEM1, 0, "新建");
file.add(0, ITEM2, 0, "打開");
return true;
}
/**
* 覆蓋該方法,響應(yīng)菜單選項(xiàng)被單擊事件
*/
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case ITEM1:
setTitle("新建文件!");
break;
case ITEM2:
setTitle("打開文件!");
break;
}
return true;
}
}
?
總結(jié)
以上是生活随笔為你收集整理的android用户界面-菜单的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交互设计师
- 下一篇: 总结2010展望2011