My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
AndroidMenu  
加入選單(Menu)
tw, menu
Updated Sep 18, 2009 by gasolin

在進一步學習 Intent 與 Activity 之前,我們先來完善我們的應用程式。 在前幾章中,我們把 「openOptionsDialog」 這個用來彈出對話框的函式,放進「calcBMI」這個按鈕元件的「OnClickListener」方法中。現在,我們要把「openOptionsDialog」 移出「OnClickListener」方法,改成按下「Menu」鍵後,跳出一個選單列(Menu Bar)。當我們點擊選單列中的選項後,才彈出 「openOptionsDialog」 的對話框。

完整的程式碼如下:

1  protected static final int MENU_ABOUT = Menu.FIRST;
2  protected static final int MENU_Quit = Menu.FIRST+1;
3
4  @Override
5  public boolean onCreateOptionsMenu(Menu menu) {
6      super.onCreateOptionsMenu(menu);
7      menu.add(0, MENU_ABOUT, 0, "關於...");
8      menu.add(0, MENU_Quit, 0, "結束");
9      return true;
10 }
11
12 @Override
13 public boolean onOptionsItemSelected(MenuItem item)
14 {
15     super.onOptionsItemSelected(item);
16     switch(item.getItemId()){
17	    case MENU_ABOUT:
18	        openOptionsDialog();
19		break;
20         case MENU_Quit:
21	        finish();
22             break;
23	 }
24	 return true;
25 }

每個選單都包含兩個部分:

  1. 建立選單
  2. 處理選項動作

「onCreateOptionsMenu」函式即選單列的主體。在 Android 機器或模擬器上按下硬體的「Menu」(選單)鍵,所彈出的選單列即是靠「onCreateOptionsMenu」函式來定義。當我們在 Activity 中定義了 「onCreateOptionsMenu」 之後,按下「Menu」(選單)鍵時,就會彈出相對應的選單列。

當我們在 Android 應用程式的選單列上選擇了相應的選項後,則是依賴「onOptionsItemSelected」函式,來負責處理選單列中各選項所個別對應的動作。

在上面的程式裡,我們定義了「關於...」與「結束」兩個選單列中的選項。我們分部分講解如下:

建立選單

在 「onCreateOptionsMenu」函式中,我們定義了兩個選單列中的選項。 分行講解如下:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    return true;
}

「onCreateOptionsMenu」這個函式是選單列的主體,它是一個「public」(公開)的函式。函式傳入一個「Menu」(選單)型別的「menu」參數。「boolean」則表示函式的返回值必須為「boolean」型別的值。因此在函式最後,我們提供函式一個返回值「true」。「@Override」表示我們要完全重寫掉已定義在「Activity」類別中的這個函式。

基於與 onCreate 函式一樣的原因,因為我們把選單列原本的動作覆載 (Override) 掉了,因此在撰寫我們自己的內容前,加上一句「super.onCreateOptionsMenu(menu)」敘述,用來呼叫「onCreateOptionsMenu」函式執行預設的動作。

menu.add(0, MENU_ABOUT, 0, "關於...");
menu.add(0, MENU_Quit, 0, "結束");

Android 每個頁面對應到一個 Activity,每個 Activity 都有一個獨立的選單列。對傳入的「menu」參數作處理就能改變選單列的內容。

我們看到,增加一個選單列中選項的格式如下:

menu.add(0, 識別符號(identifer), 0, 字串或資源識別符號);

最後一欄「字串或資源識別符號」就是顯示在螢幕上的敘述。 而「識別符號」的目的則是作為這個選項的標籤,以供後續處理選項動作時,更容易辨認出所對應的選項。

protected static final int MENU_ABOUT = Menu.FIRST;
protected static final int MENU_Quit = Menu.FIRST+1;

我們看到 MENU_ABOUT 識別符號的定義,是一個固定的常數型別(static final int)。「Menu.FIRST」則代表識別選單開頭的數字,當然我們也可以把這「Menu.FIRST」代號直接用任意數字替換,看看程式會發生什麼事。

處理選項動作

在「OptionsItemSelected」函式中,我們分行講解如下:

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    super.onOptionsItemSelected(item);
    return true;
}

「onOptionsItemSelected」這個函式是處理所有選項的主體,和「onCreateOptionsMenu」函式相同,也是一個「public」(公開)的函式。「onOptionsItemSelected」函式傳入了一個「MenuItem」(選項)型別的「item」參數。「boolean」表示函式的返回值必須為「boolean」型別的值。因此在函式最後,我們提供函式一個返回值「true」。 「super.onOptionsItemSelected(item);」表示我們要先執行已定義在「Activity」類別中原本的「onOptionsItemSelected」函式內容,後面再接著執行我們為此函式新定義的動作。

    switch(item.getItemId()){

我們可以用「item.getItemId()」函式來取得在螢幕上選取的選項所對應的識別符號代碼(identifer)。

    switch(識別符號代碼){
        ....
    }

在 swith 敘述中,我們根據從「item.getItemId()」函式取得的識別符號代碼判斷, 根據選到的識別符號代碼,作相應處理。

    case MENU_ABOUT:
        openOptionsDialog();
        break;
    case 
        ....
        break;

在「onOptionsItemSelected」函式中收到 「MENU_ABOUT」 識別符號時,我們呼叫 「openOptionsDialog」 函式來彈出對話框。

    case MENU_Quit:
        finish();
        break;

在「onOptionsItemSelected」函式中收到 「MENU_Quit」 識別符號時,我們呼叫 Android 內建的 「finish」函式來關閉這個 Activity。因為我們的「BMI」應用程式只由一個「Bmi」Activity 組成,所以當我們呼叫「finish」函式來關閉「Bmi」這個 Activity,就等於直接關閉了這個「BMI」應用程式。

而事實上, 在 Android 平台上,無論是開發者或是使用者,都不需要自己來關閉 Activity。 因為 Android 虛擬機(Dalvik) 接手了什麼時候 Activity 該啟動或關閉的工作。整個 Android Activity 的運作流程,將在後續章節中作講解。

< 初見 Intent | 回目錄 | 定義 Android 清單 >


對於本章,您還期望知道什麼樣的內容呢?請在下方提出建議!

Comment by iceliush...@gmail.com, May 6, 2009

很好的资料,学习中~~

Comment by iceliush...@gmail.com, May 6, 2009

我的menu的openOptionsDialog()和finish()都很好用啊!

Comment by cmy1...@gmail.com, Jun 18, 2009

先謝謝您的文章,是很不錯的初學資料。

但這節好像有一個筆誤,在倒數第二段,

"在「onOptionsItemSelected」函式中收到 「MENU_ABOUT」 識別符號時,我們呼叫 Android 內建的 「finish」函式來關閉這個 Activity。"

其中的MENU_ABOUT應該是MENU_Quit。

Comment by project member gasolin, Jun 18, 2009

cmy1225, fixed, thanks!

Comment by xxlfor...@gmail.com, Mar 2, 2010

奇怪,我照着做了按了键盘上的menu建还是没有看到自己定义的这个选单呢?

Comment by xxlfor...@gmail.com, Mar 2, 2010

哈哈,懂了,sorry,刚才操作失误,一开始就按menu,所以看不到~

Comment by wang4...@gmail.com, Mar 21, 2010

在模擬器上執行,按下menu中的(關於),對話框沒有顯示出來呢。

Comment by project member gasolin, Mar 21, 2010

參考「加入對話框(Dialog)」那節加對話框進去

Comment by bandai...@gmail.com, Apr 8, 2010

G大, 如果將onCreateOptionsMenu的RETURN改為FALSE就會開不出MENU. 但當我把OnOptionsItemSelected?的REUTRN值改為FALSE時卻沒甚麼效果, 其實它應該會有甚麼作用的?

Comment by chui.hin...@gmail.com, Apr 30, 2010

It's there any changes for the xml declaration for menu? P.S. You can just reply in Chinese. =]

Comment by hufu...@gmail.com, May 19, 2010

大哥 請問要如何關閉整個程式而不只是單一activity

Comment by KateLin013@gmail.com, May 26, 2010

想請問一下,關於這節中, 不知道為什麼小弟在以下幾行都會出紅底線.. onCreateOptionsMenu(Menu menu) onCreateOptionsMenu(Menu) 還有就是 onOptionsItemSelected(MenuItem? item) onOptionsItemSelected(item); 以下是錯誤訊息: The method onCreateOptionsMenu(Menu) of type new View.OnClickListener?(){} must override or implement a supertype method The method onCreateOptionsMenu(Menu) is undefined for the type Object

想請問該怎麼解決呢>< ?? 麻煩囉,謝謝

Comment by project member gasolin, May 26, 2010

比對 http://code.google.com/p/androidbmi/source/browse/#svn/trunk 這邊的原始碼看看您有沒輸入錯誤

Comment by Sky.C...@gmail.com, Jun 2, 2010

會有紅底線的應該是少了

import android.view.Menu; import android.view.MenuItem?;

Comment by s9614...@gmail.com, Jul 13, 2010

請問要怎麼在menu中每個選項前增加小圖示呢?

Comment by wmc...@gmail.com, Jul 17, 2010

我把上面兩個函式加進去bmi.java後執行

按menu結果也是一點事情也沒發生

然後按計算bmi之後再按menu也是一樣

上面有說參考一下加入對話框那邊

可是...我沒概念

不懂要怎樣加入

有誰可以幫我一下@@?

Comment by lozb0...@gmail.com, Aug 16, 2010

我剛剛也有按menu的關於但是一點反應也沒有的狀況 後來發現是我的function 有打錯字 onCreateOptionsMenu()

改完後就會跳出對話框了

Comment by a6309...@163.com, Nov 30, 2010

有红底的话双击左边的红点 import 进去一般就可以了 缺

Comment by jackzzj...@gmail.com, Dec 28, 2010

onCreateOptionsMenu 裡的 Option"s" 要小心 !!!

Comment by moses781...@gmail.com, Jan 21, 2011

如果附圖的話會很好

Comment by ychen...@gmail.com, Mar 6, 2011

請問我想在書中一樣加入icon menu.add(0,MENU_QUIT,0,"結束").setIcon(R.drawable.emblem_unreadable); 圖片丟在drawable-mdpi內

但是執行menu的結果

The application BMI (process com.demo.android.bmi)has stopped unexpecteddly.Please try again 只有強制關閉的選項 = =(Force close)

但是如果只用內建的圖片 menu.add(0,MENU_ABOUT,0,"關於...").setIcon(android.R.drawable.ic_menu_help); 卻是可以執行的結果 請問發生了甚麼事情呢?

Comment by how0...@gmail.com, Jul 13, 2011

我本來也遇到按下"關於"後無法顯示。

仔細看了一下,原來我漏了break;

public boolean onOptionsItemSelected(MenuItem? item) {
super.onOptionsItemSelected(item); switch(item.getItemId()) {
case MENU_ABOUT: openOptionsDialog();break;==>我漏掉的那一個.... case MENU_QUIT: finish();break;
} return true;
}

希望有幫助!!!少了的話會直接跳出程式!!!

Comment by lam.chi....@gtempaccount.com, Aug 11, 2011

the teaching is very useful thx

Comment by celia7...@gmail.com, Aug 30, 2011

請問public boolean onOptionsItemSelected(MenuItem? item) {

// TODO Auto-generated method stub switch(item.getItemId()){ case MENU_ABOUT:
openOptionsDialog(); break;
case MENU_QUIT:
finish(); break;
} return super.onOptionsItemSelected(item);
}

我的openOptionsDialog底下會出現紅線,顯示The method openOptionsDialog() is undefined for the type Main 不曉得該如何修正錯誤??????

Comment by Lal...@gmail.com, Oct 31, 2011

注意openOptionsDialog 書寫的位置 不要把他包在OnClickListener?裡面了

Comment by ckw...@gmail.com, Dec 5, 2011

我並沒有看到關於與結束的menu,是否我哪裡漏掉,煩請大大指正一下。


Sign in to add a comment
Powered by Google Project Hosting