本文參考自官方文檔:https://developer.android.com/guide/topics/ui/menus.htmlhtml
Android爲了維護app之間一個統一的操做習慣,提供了Menus來處理用戶和Activity之間的一些交互。可是在不一樣的系統版本上面推薦的Menu不同。好比在android 3.0如下,因爲Google會要求全部設備生產商提供一個菜單的實體鍵,因此在3.0一下菜單的主要彈出方式就是點擊菜單實體鍵,彈出6個條目的菜單面板。在3.0之後,引入ActionBar,打開菜單行爲轉變成點擊ActionBar上面的overflow按鈕。這兩種菜單面板的操做通常都是影響到整個app的操做。
下圖是3.0一下的Option Menu的樣子:
android
這是3.0上的ActionBar的樣子:app
固然除了上面提到的菜單面板,Android還提供了上下文菜單(Context menu)和彈出菜單(Popup Menu)。儘管存在三種不一樣的菜單,可是Android提供了一個統一操做的API。ide
Android中的全部菜單項的佈局文件都是在res/menu目錄下定義的,佈局文件並無和某一種菜單類型綁定,這就是爲何前面說有統一操做的API。xml定義菜單的規則是:頂層元素必須是Menu;在Menu中能夠放置item和group;item表示菜單中的一項;group能夠包含多個item,其中的全部item都會共享某一些屬性。item中又能夠包含Menu項,這是嵌套菜單(多級菜單)。函數
前面已經說到,選項菜單在3.0先後版本存在一些差異。在Fragment和Activity中均可以建立選項菜單,系統會首先顯示Activity中建立的item,而後按照fragment加入的順序添加item。在3.0一下時,onCreateOptionsMenu是在點擊菜單鍵時觸發;在3.0以上,則是在Activity建立時就會調用。佈局
響應點擊事件,能夠在onOptionsItemSelected中進行。注意這個事件處理函數須要返回一個boolean值。若是已經處理了此次點擊須要返回true,不然直接調用super.onOptionsItemSelected()(返回fasle)。這個事件的處理流程是,事件先被送到Activity,而後按照先進先達的順序,直至莫一個fragement處理了此次點擊或者全部的fragment都已經遍歷了。ui
能夠在菜單的item中指定android:onClick
,這個點擊事件的處理函數必須是Activity中籤名爲public 而且接受一個MenuItem的參數。code
更新菜單中的選項,咱們能夠經過onCreateOptionsMenu來建立菜單項,可是若是想在運行時改變菜單中的選項,能夠重寫onPrepareOptionsMenu方法來實現。在3.0如下,這個方法會在菜單鍵每次按下的時候觸發;在3.0以上,因爲ActionBar是一直顯示的,因此咱們若是須要改變菜單,能夠主動調用invalidateOptionsMenu()
,而後系統會去走onPrepareOptionsMenu。xml
Contextual Menu主要多用於和界面特別是AdapterView中的某一個item進行交互,經過長按控件來呼出一個Action Menu。若是說Option menu(Actionbar)上面的菜單選項是針對整個app的範圍,那麼Contextual Menu從名字就能夠看出來是針對當前context範圍內的操做。存在兩種方式:htm
下圖左邊是floating context Menu,右邊是Contextual action mode
floating context menu是3.0一下版本建議使用的,針對當前Context的一個操做面板,經過長按指定控件呼出。長按事件若是也被監聽,那麼會先執行長按事件,再執行onContextItemSelected。若是長按事件處理返回true,那麼context Menu不會被呼出:
一樣須要注意的是在處理事件時,也是由Activity最早接收,而後按照加入順序分發到每個Fragment。
從上圖能夠看到Contextual action和ActionBar很有幾分類似,可是二者直接並沒有直接關聯。在3.0一下版本中,咱們須要使用support包中的兼容方案。
單個View使用步驟以下:
在AdapterView中使用,步驟以下:
API level 11加入。在android中還提供了一種用來相對於界面上已經存在的一個控件的菜單,好比相似於ActionBar上面的overflow。
使用Popup Menu的步驟以下:
須要注意的是PopupMenu彈出的位置是自適應的,主要看這個View在那個地方有空間,就會在哪一個方向上面彈出來。
選擇菜單和前面所說起的菜單類型不一樣,它僅僅是一種菜單項的表現形式。在本文以前說起的全部菜單中,每個菜單項的呈現方式都是簡單的文字(或者icon),若是咱們要加入一種單選框或者複選框的效果,可使用item的checkable屬性。效果以下圖:
須要注意的是,在option Menu中,若是一個菜單項是以icon的方式顯示出來,那麼它將不會顯示選擇框。
咱們亦能夠經過group來爲一組item設置選擇條件,這纔是它原本的意義。android:checkableBehavior
能夠設置成radio 或者checkbox或者none,默認應該是checkbox。
選擇菜單項是不能保存狀態的,若是app退出,下次再進入狀態就不存在了。
若是咱們須要在菜單項中經過Intent啓動另一個Activity,Menu提供了專門的類型來處理,這就是Intent Options。並且意圖菜單項還能夠在系統中解析這個Intent是否可以被Activity瞭解,若是系統中沒有Activity可以接受這個Intent,那麼這個意圖菜單項將不會展現出來。使用步驟以下:
CATEGORY_ALTERNATIVE and/or CATEGORY_SELECTED_ALTERNATIVE
addIntentOptions方法返回增長的item數目,因此經過Intent解析的item都會被加入菜單中。這個菜單項的item title就是intent-filter的android:label,icon是application icon
感受這個東東和settings等系統模塊同樣,在中國開發者的眼中根本不會去用它,因此老外才會感嘆中國作的app怎麼這麼難用,每一個應用的風格都不同。。。