android基礎知識22:菜單menu 01——概述

來源:互聯網
上載者:User

1、概述

        菜單是Activity的一個重要組成部分。它為使用者操作提供了很爽的途徑。Android提供了一個簡單的架構來向程式中添加標準菜單 .

        共有三種菜單:

  • 選項菜單

        一個activity的功能表項目們的主要集合。當你按MENU按鈕時(硬體上的)就會出現。如果你的程式跑在 Android 3.0或以上,你可以通過把功能表項目作為 "action items"直接放在Actiion Bar上來提供快速選擇能力。

  • 快顯功能表

        一列浮動的功能表項目們,當使用者對一個註冊了快顯功能表的View按住不放時就會出現。

  • 子功能表

        也是一列浮動的功能表項目們,當使用者點擊一個包含嵌入菜單的功能表項目時出現。
        本文檔闡明怎樣建立各類型的菜單,怎樣使用XML來定義菜單的內容以及如何在Activity中定義回呼函數來響應功能表項目。

1.1 建立一個菜單資源

        你需要在一個XML 菜單資源中定義一個菜單而不是在代碼中,然後在代碼中inflate這個菜單資源。使用菜單資源來定義菜單是一個很佳的做法,因為這樣可以使介面與代碼分離。並且在XML中更容易設計你的菜單。
        要建立一個菜單資源,先在你項目的res/menu/下建立一個XML檔案,然後用以下元素建立菜單:

  • <menu>

        定義一個菜單,它是功能表項目的容器。 <menu>必須是檔案的根節點,其內部可包含一個或多個<item>和<group> 元素。

  • <item>

        建立一個功能表項目。功能表項目中可以繼續包含<menu>元素,此時它就具有了子功能表。

  • <group>

        一個可選的,不可見的,容納<item> 元素的容器。它使你能夠對功能表項目進行分類,從而使同類的功能表項目共用一些屬性,比如活動狀態,可見狀態等。請看 Menu groups節。

        以下是一個菜單的例子,菜單名為 game_menu.xml:

<?xml version="1.0" encoding="utf-8"?>  <menu xmlns:android="http://schemas.android.com/apk/res/android">      <item android:id="@+id/new_game"            android:icon="@drawable/ic_new_game"            android:title="@string/new_game" />      <item android:id="@+id/help"            android:icon="@drawable/ic_help"            android:title="@string/help" />  </menu>  

        此例中定義了兩個功能表項目,每個包含屬性有:

  • android:id

        一個資源ID來標誌功能表項目,當使用者選擇某個功能表項目時,程式可以用這個ID來識別這個功能表項目.

  • android:icon

        引用一個drawable用於功能表項目的表徵圖。

  • android:title

        引用一個字串用於功能表項目的標題。
        還有很多可以在<item>中使用的屬性,還包含指定功能表項目如何在Action Bar中顯示的屬性。更多關於XML文法和菜單資源屬性的知識,請看 Menu Resource節。

1.2 Inflating 一個菜單資源

        在 代碼中,使用方法 MenuInflater.inflate()你可以inflate(把一個XML資源轉換為程式中的對象)一個菜單資.例如,下面的代碼在回調方法 onCreateOptionsMenu()中把檔案 game_menu.xml inflate成一個菜單對象,從而作為這個Activity的選項菜單使用:

@Override  public boolean onCreateOptionsMenu(Menu menu) {      MenuInflater inflater = getMenuInflater();      inflater.inflate(R.menu.game_menu, menu);      return true;  }  

        方 法 getMenuInflater() 返回Activity的一個 MenuInflater ,使用這個對象,你可以調用 inflate(), 把菜單資源轉換為 菜單 對象.在這個例子中,菜單資源被inflate到方法onCreateOptionsMenu()的參數 Menu中.

2、建立一個選項菜單

       選項菜單裡應該包含基本的activity動作和必須的導航條目 (例如,一個開啟程式設定的功能表項目). 選項菜單的功能表項目有兩種不同的選擇方法,一是功能表項目按鈕,二是通過 Action Bar (在Android 3.0及以上版本中).

                                        

圖1:瀏覽器中的選項菜單                                                        圖 2. Email程式中的動作欄,具有兩個動作和一個溢出菜單

        當 運行於Android 2.3及更低版本時,選項菜單出現在螢幕的底部,見圖1.當開啟選項菜單時,首先映入眼帘的是表徵圖菜單,它有六個功能表項目,如果你加入了多於六個功能表項目,系 統會把第六個功能表項目和後面的功能表項目放到溢出菜單中,使用者可以通過 "More"功能表項目開啟它們.
        Android 3.0及以後版本中,選項功能表項目被放在Action Bar上.Action Bar位於Activity的頂部傳統的Title bar所在的位置.預設情況下,所有的來自選項菜單的功能表項目都衣放入溢出菜單中.使用者可以觸擊Action bar右邊的菜單表徵圖以開啟之.但是,你也可以把功能表項目作為"action items"直接放到 Action Bar上 ,像圖2所示那樣.
        當系統第一次建立選項菜單時,它調用你的activity的方法 onCreateOptionsMenu() . 重寫這個方法並且為傳入的參數 Menu 建立執行個體.Menu 是通過inflate一個菜單資源建立的,如下:

@Override  public boolean onCreateOptionsMenu(Menu menu) {      MenuInflater inflater = getMenuInflater();      inflater.inflate(R.menu.game_menu, menu);      return true;  }  

        你也可以在代碼中產生menu,然後使用方法 add() 添加功能表項目.
        注意:在Android 2.3 及更低版本中,當使用者第一次開啟選項菜單時系統調用 onCreateOptionsMenu() 建立選項菜單,但是在Android 3.0及更高版本中, 系統在Activity一建立時就建立選項菜單,為的是建立Action Bar.

2.1 響應使用者動作

        當使用者選擇一個功能表項目 (也包括Action Bar上的動作項), 系統會調用你的activity的方法 onOptionsItemSelected() .這個方法會在參數中傳入選擇的功能表項目.你可以通過調用方法getItemId()定位這個功能表項目 ,這個方法會返回功能表項目的唯一ID (在菜單資源檔中以android:id屬性定義或在調用方法add()時傳入的整數). 你可以使用已知的功能表項目來匹配這個ID並執行相關的動作,例如:

@Override  public boolean onOptionsItemSelected(MenuItem item) {      // Handle item selection      switch (item.getItemId()) {      case R.id.new_game:          newGame();          return true;      case R.id.help:          showHelp();          return true;      default:          return super.onOptionsItemSelected(item);      }  }  

        在 這個例子中, getItemId() 擷取所選功能表項目的ID並在switch語句中與資源檔中所有菜單ID比較。當switch語句中成功處理了功能表項目,就返回 true 以表明所選 的功能表項目被處理了。否則,default 語句會把功能表項目傳給父類,也許父類會處理這個功能表項目 (如果你直接從 Activity派生,那麼父類會返回false, 但是把未處理的功能表項目傳給父類而不是直接返回false是一個好習慣.)
        另外, Android 3.0 增加了在菜單資源XML檔案中定義功能表項目的點擊行為的能力,這個能力通過 android:onClick 屬性定義 。所以你不需要實現 onOptionsItemSelected(). 使用 android:onClick 屬性,你可以指定一個方法在功能表項目被選擇時調用. 你的 activity 必須實現在屬性android:onClick中指定的方法,它接受一個MenuItem 參數---當系統調用這個方法時選中的菜單從這個參數傳入。
        小 技巧:如果你的程式中包含多個 activitie並且它們提供相同的選項菜單,應考慮建立一個只實現了 onCreateOptionsMenu() 和 onOptionsItemSelected()的activity 類,然後讓那些提供相同選項菜單的activity都從這個類派生.通過這種方式,你只需為這個類的子孫們管理一組代碼。
        如果你想在孫子 activitie們中添加功能表項目,只需重寫 onCreateOptionsMenu(). 在其中調用 super.onCreateOptionsMenu(menu) ,於是原始的菜單被建立,然後通過方法menu.add()添加新功能表項目。你也可以重寫父類的方法來建立另外的功能表項目們。

3、在運行時改變功能表項目們

        一旦activity被建立,方法onCreateOptionsMenu() 只會被調用一次(前面已經說過).系統會儲存並重用這個菜單,直到你的activity被銷毀.如果你想在菜單建立後再去改變它怎麼辦呢?你必須重寫方法 onPrepareOptionsMenu() . 它會傳給你已建立的菜單的執行個體.在你想跟據應用的狀態刪除,添加,disable, or enable功能表項目們的時候就用到這個函數了.
        在 Android 2.3和其之前的版本,系統在每次開啟選項菜單時都會調用 onPrepareOptionsMenu() .
        在 Android 3.0 及以後版本中,你必須在你想更新菜單之前主動調用方法 invalidateOptionsMenu() , 因為菜單是一直開啟的.系統之後會調用onPrepareOptionsMenu() ,於是你就可以更改功能表項目了.
        注: 你永遠不要更改當前具有焦點的View的選項菜單.當處於觸摸模式 (使用者沒有使用軌跡球或方向鍵), views不能取得焦點,所以你永遠不能基於焦點來修改選項菜單的功能表項目. 如果你想為View提供上下文敏感的功能表項目,使用 Context Menu.
        如果你正在開發 Android 3.0 或更高版本之上的應用,還需閱讀 Action Bar 的開發指南.

4、操作功能表

        一個操作功能表跟PC上的右鍵菜單類似.你應使用操作功能表為使用者介面上的某個部分提供動作選擇功能.在Android中,一個操作功能表會在使用者長按一個介面條目時出現.
        你可以為任何View建立操作功能表,但是在 ListView中是最常用到操作功能表的.每當使用者在一個ListView項上長按,並且這個ListView註冊了操作功能表,那麼被按的 list item就會彈出操作功能表 (在連絡人應用中就示範了這個過程).
Register a ListView
        如果你的activity使用一個ListView並且你希望所有的list items都提供一個操作功能表,應把ListView傳給方法registerForContextMenu(),例如:
registerForContextMenu(getListView());
        為了使view提供操作功能表,你必須為這個View向系統註冊操作功能表.調用方法 registerForContextMenu() 並傳入要快顯功能表的 View 作為參數即可.當這個View被長按時,它就會顯示一個操作功能表.
        為了定義操作功能表的樣子和行為,需重寫你的activity的操作功能表回調方法:onCreateContextMenu() 和onContextItemSelected().
        例如,下面是一個 onCreateContextMenu() ,使用了資源檔 context_menu.xml :

@Override  public void onCreateContextMenu(ContextMenu menu, View v,                                  ContextMenuInfo menuInfo) {    super.onCreateContextMenu(menu, v, menuInfo);    MenuInflater inflater = getMenuInflater();    inflater.inflate(R.menu.context_menu, menu);  }  

        MenuInflater 被用於從一個 菜單資源inflate出一個菜單. (你也可以使用 add() 來添加功能表項目們) .回呼函數的參數中包含了使用者所選擇的View 和一個ontextMenu.ContextMenuInfo 對象,它可以提供被選擇的View的更多的資訊.你可以使用這些參數來決定哪個操作功能表應被建立.但是在這個例子中,Activity所有的操作功能表都是相同的.
        然後,當使用者從操作功能表選擇一個功能表項目時,系統會調用方法 onContextItemSelected(). 下面的例子展示了如何處理被選擇的功能表項目:

@Override  public boolean onContextItemSelected(MenuItem item) {    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();    switch (item.getItemId()) {    case R.id.edit:      editNote(info.id);      return true;    case R.id.delete:      deleteNote(info.id);      return true;    default:      return super.onContextItemSelected(item);    }  }  

        這些代碼與選項菜單中的例子代碼基本相同.getItemId() 從所選的功能表項目擷取菜單ID,並且使用switch語句匹配菜單ID與對應的處理.並且同於選項菜單的例子,default語句調用父類的同一方法處理未被我們處理的功能表項目.
        在此例中,被選擇的View條目是一個 ListView條目.為了在選擇的一個view條目上執行相應的動作,應用程式需要知道View條目的list ID.為了獲得 list ID,程式中調用了 getMenuInfo(), 它返回一個 AdapterView.AdapterContextMenuInfo 對象,這個對象包含了條目的list ID.本地方法editNote()和deleteNote()接受這個list ID用於執行一些作.

        注: 操作功能表項目不支援表徵圖或快速鍵.

5、子功能表

        一個子功能表是一個在已有菜單的某個功能表項目上開啟的菜單.你可以向任何菜單添加子功能表.當你的程式擁有很多功能並可按類別組織起來,那麼子功能表是最佳選擇.比如PC 程式中的功能表列 (File, Edit,View等等.).
        當建立你的菜單資源時,你可以添加一個<menu> 元素作為一個<item>元素的孩子來建立子功能表.例如:

<?xml version="1.0" encoding="utf-8"?>  <menu xmlns:android="http://schemas.android.com/apk/res/android">      <item android:id="@+id/file"            android:icon="@drawable/file"            android:title="@string/file" >          <!-- "file" submenu -->          <menu>              <item android:id="@+id/create_new"                    android:title="@string/create_new" />              <item android:id="@+id/open"                    android:title="@string/open" />          </menu>      </item>  </menu>  

        當使用者從一個子功能表中選擇一個功能表項目, 父菜單的響應功能表項目選擇的回調方法會接收到事件.例如,如果上述菜單是一個選項菜單,那麼方法 onOptionsItemSelected() 就會被調用.
        你也可以使用 addSubMenu()來動態添加子功能表到一個菜單中.這個方法會返回一個新的 SubMenu 對象, 你可以使用add()方法向這個SubMenu對象添加功能表項目.

參考資料:

android菜單詳解一:概述
android菜單詳解二:選項菜單
android菜單詳解三:操作功能表
android菜單詳解四:子功能表

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.