Android中的菜單

本文參考自官方文檔: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

在XML中定義菜單項

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,一般在長按ListView中的某一項以後出現。
  • Contextual action mode,會顯示出一個ActionBar,它是一種ActionMode的實現,在3.0系統以上才能使用。

下圖左邊是floating context Menu,右邊是Contextual action mode

floating context menu

floating context menu是3.0一下版本建議使用的,針對當前Context的一個操做面板,經過長按指定控件呼出。長按事件若是也被監聽,那麼會先執行長按事件,再執行onContextItemSelected。若是長按事件處理返回true,那麼context Menu不會被呼出

  1. 經過Activity或者Fragment的registerForContextMenu,傳入一個View,爲它註冊一個floating context menu
  2. 實現onCreateContextMenu,來建立Menu條目
  3. 實現onContextItemSelected處理選擇某一個菜單的事件

一樣須要注意的是在處理事件時,也是由Activity最早接收,而後按照加入順序分發到每個Fragment。

contextual action mode

從上圖能夠看到Contextual action和ActionBar很有幾分類似,可是二者直接並沒有直接關聯。在3.0一下版本中,咱們須要使用support包中的兼容方案。
單個View使用步驟以下:

  1. 實現ActionMode.CallBack,這裏主要實現action mode的主要邏輯
  2. 在合適的時候經過Activity或者fragment的startSupportActionMode來進入一個contextaul action mode。

在AdapterView中使用,步驟以下:

  1. 實現AbsListView.MultiChoiceModeListener,其實這個玩意繼承自ActionMode.CallBack,增長了onItemCheckedStateChanged函數,用來處理當AbsListView中某一項的選擇狀態改變時的操做。
  2. 經過設置AbsListView的MultiChoiceModeListener,注意,這裏默認進入Action Mode的動做是長按某一個Item。

API level 11加入。在android中還提供了一種用來相對於界面上已經存在的一個控件的菜單,好比相似於ActionBar上面的overflow。

使用Popup Menu的步驟以下:

  1. 經過context和相對的View建立PopupMenu對象。
  2. 經過popupMenu對象來設置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,那麼這個意圖菜單項將不會展現出來。使用步驟以下:

  1. 在定義的Intent中增長一個category:CATEGORY_ALTERNATIVE and/or CATEGORY_SELECTED_ALTERNATIVE
  2. 調用Menu.addIntentOpions()。

addIntentOptions方法返回增長的item數目,因此經過Intent解析的item都會被加入菜單中。這個菜單項的item title就是intent-filter的android:label,icon是application icon

感受這個東東和settings等系統模塊同樣,在中國開發者的眼中根本不會去用它,因此老外才會感嘆中國作的app怎麼這麼難用,每一個應用的風格都不同。。。

相關文章
相關標籤/搜索