《Android》『OptionsMenu、SubMenu、ContextMenu』- 選項選單、子選單、長按選單元件的基本用法
《Android Developers 參考文獻》
《簡單介紹》
在早期的 Android 手機上,我們通常都可以看到一個實體的 Menu 鍵(現在大多已轉變成虛擬按鈕),而這個 Menu 鍵叫出來的就是 android 程式的功能表選單,在 Android 中,提供了三種不同類型的選單元件,分別是 OptionsMenu、SubMenu 以及 ContextMenu,在這邊我們就一個一個來介紹。
《基本用法》
與大部分的 Android 元件一樣,選單內容的建構可以分為靜態與動態生成,差別在於靜態是在 xml 資源檔中先設定好資料,而動態則是於程式碼執行的過程中建立選單的內容,這邊我們直接以動態生成的方式,說明不同選單元件的使用方式。(靜態生成可以參考 ActionBar 這篇)
OptionsMenu – 選項選單
透過覆寫 onCreateOptionsMenu() 方法,我們可以建立一個基本的選項選單 OptionsMenu,程式碼如下 –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
package ... import ... public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public boolean onCreateOptionsMenu(Menu menu) { //(群組ID, 選項ID, 選項排列順序, 選項名稱) MenuItem menu1 = menu.add(0,10,1,"item_0_1"); MenuItem menu2 = menu.add(0,20,2,"item_0_2"); menu1.setIcon(R.drawable.icon); menu2.setIcon(R.drawable.icon); menu1.setAlphabeticShortcut('a'); //設定字母快捷鍵為"a" menu2.setAlphabeticShortcut('b'); //設定字母快捷鍵為"b" menu1.setNumericShortcut('1'); //設定數字快捷鍵為"1" menu2.setNumericShortcut('2'); //設定數字快捷鍵為"2" menu2.setShortcut('1','b');//設定快捷鍵為"1" 與 "b" menu1.setOnMenuItemClickListener(mMenuItemClickListener);//設定按鈕監聽器 menu2.setOnMenuItemClickListener(mMenuItemClickListener); return super.onCreateOptionsMenu(menu); } MenuItem.OnMenuItemClickListener mMenuItemClickListener //按鈕監聽器,其觸發時機與 onOptionsItemSelected 類似。 = new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { if(item.getItemId() == 10) //用 Item id 識別觸發此方法的按鍵 { Toast.makeText(getApplicationContext(), "item_0_1 Click", Toast.LENGTH_SHORT).show(); } else if(item.getItemId() == 20) { Toast.makeText(getApplicationContext(), "item_0_2 Click", Toast.LENGTH_SHORT).show(); } return false; } }; @Override public boolean onOptionsItemSelected(MenuItem item) //當 Menu 有選項被按下時觸發 { Toast.makeText(getApplicationContext(), "item.getItemId(): " + item.getItemId() +", "+ "item.getTitle(): " + item.getTitle() + ", "+ "item.getOrder(): " + item.getOrder(), Toast.LENGTH_SHORT).show(); return super.onOptionsItemSelected(item); } @Override public void onOptionsMenuClosed(Menu menu) //當 Menu 關閉時觸發 { Toast.makeText(getApplicationContext(), "關閉了選項選單", Toast.LENGTH_SHORT).show(); super.onOptionsMenuClosed(menu); } } |
MainActivity.java
我們在 onCreateOptionsMenu(Menu menu) 中,宣告了兩個基於 MenuItem 類別的物件,分別取名為 menu1、menu2,並將這兩個物件加入至 menu 中回傳,意思就是我們把 Menu 選單設定了兩個按鈕,而這兩個按鈕就是 menu1 與 menu2。
常用到的設定方法條列如下 –
@Override
public boolean onCreateOptionsMenu(Menu menu)
➥初始化選單內容。
@Override
public boolean onOptionsItemSelected(MenuItem item)
➥選單項選取時觸發處理,觸發時機與 OnMenuItemClickListener 監聽器類似。
@Override
public void onOptionsMenuClosed(Menu menu)
➥選單關閉時觸發處理
add()
增加選單項。
addSubMenu()
增加子選單項。
setTitle()、getTitle()
設定、取得選單項標題。
setOrder()、getOrder()
設定、取得選單項順序。
setIcon()、getIcon()
設定、取得選單項圖示。
setAlphabeticShortcut()、getAlphabeticShortcut()
設定、取得選單項之字母快捷鍵。
setNumericShortcut()、getNumericShortcut()
設定、取得選單項之數字快捷鍵。
setShortcut()
設定選單項之字母與數字快捷鍵。
setOnMenuItemClickListener()
SubMenu – 子選單
在剛剛的例子中,我們成功的為 Menu 選單加入了兩個選單項,但是這兩個選單項是只有一層的,若是我們想做出多層的效果呢?其實很簡單,我們先前在宣告選單項的時候,是使用 MenuItem 類別來建立物件,若是我們想做出帶有子選單的選單項,則改用 SubMenu 類別來建立即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
package ... import ... public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override public boolean onCreateOptionsMenu(Menu menu) { //(群組ID, 選項ID, 選項排列順序, 選項名稱) SubMenu menu1 = menu.addSubMenu(0, 10, 1, "menu_0_1"); //宣告一個有子選單的選單 //(群組ID, 選項ID, 選項排列順序, 選項名稱) MenuItem subMenu1 = menu1.add(1, 101, 1, "menu_1_1"); //定義子選單的選單項 MenuItem subMenu2 = menu3.add(1, 102, 2, "menu_1_2"); MenuItem subMenu3 = menu3.add(1, 103, 3, "menu_1_3"); MenuItem subMenu4 = menu3.add(1, 104, 4, "menu_1_4"); subMenu1.setOnMenuItemClickListener(mMenuItemClickListener); subMenu2.setOnMenuItemClickListener(mMenuItemClickListener); subMenu3.setOnMenuItemClickListener(mMenuItemClickListener); subMenu4.setOnMenuItemClickListener(mMenuItemClickListener); } MenuItem.OnMenuItemClickListener mMenuItemClickListener = new MenuItem.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { if(item.getItemId() == 10) //用 Item id 識別觸發此方法的按鍵 { Toast.makeText(getApplicationContext(), "menu_0_1 Click", Toast.LENGTH_SHORT).show(); } else if(item.getItemId() == 101) { Toast.makeText(getApplicationContext(), "menu_1_1 Click", Toast.LENGTH_SHORT).show(); } else if(item.getItemId() == 102) { Toast.makeText(getApplicationContext(), menu_1_2 Click", Toast.LENGTH_SHORT).show(); } else if(item.getItemId() == 103) { Toast.makeText(getApplicationContext(), "menu_1_3 Click", Toast.LENGTH_SHORT).show(); } else if(item.getItemId() == 104) { Toast.makeText(getApplicationContext(), "menu_1_4 Click", Toast.LENGTH_SHORT).show(); } return false; } }; @Override public boolean onOptionsItemSelected(MenuItem item) { Toast.makeText(getApplicationContext(), "item.getItemId(): " + item.getItemId() +", "+ "item.getTitle(): " + item.getTitle() + ", "+ "item.getOrder(): " + item.getOrder(), Toast.LENGTH_SHORT).show(); return super.onOptionsItemSelected(item); } } |
MainActivity.java
宣告的方式與前面幾乎一樣,這邊要特別說明一下的是每個 Menu 選單項在宣告的時候,都會附帶一個群組 ID 以及唯一的選單項 ID,我們透過群組 ID 劃分不同性質的 Menu 選單項,並利用選單項 ID 來識別不同的選單項。
ContextMenu – 長按選單
ContextMenu 類別繼承自 Menu 類別,因此其很多方法都與 Menu 類別類似。長按選單的意思,就是當我們長按某一個介面元件以後,會彈跳出來的選單視窗,在 Android 中,我們可以在某個 View 物件上,註冊長按選單,如此一來,使用者便可以透過長按該 View 物件來呼叫長按選單。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
package ... import ... public class MainActivity extends Activity { EditText editText1, editText2; @Override public void onCreate(Bundle savedInstanceState) { editText1 = (EditText)findViewById(R.id.editText1); editText2 = (EditText)findViewById(R.id.editText2); this.registerForContextMenu(editText1); //為 editText1 註冊長按選單 this.registerForContextMenu(editText2); //為 editText2 註冊長按選單 } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { menu.setHeaderIcon(R.drawable.icon); //設定長按選單標題圖示 menu.setHeaderTitle(R.string.app_name); //設定長按選單標題文字 if(view == editText1) //設定長按 editText1 時的選單內容 { menu.add(0, 10, 1, "menu_0_1"); menu.add(0, 20, 2, "menu_0_2"); menu.add(0, 30, 3, "menu_0_3"); menu.add(0, 40, 5, "menu_0_4"); } else if(view == editText2) //設定長按 editText2 時的選單內容 { menu.add(1, 50, 1, "menu_1_1"); menu.add(1, 60, 2, "menu_1_2"); } super.onCreateContextMenu(menu, view, menuInfo); } @Override public boolean onContextItemSelected(MenuItem item) { switch(item.getItemId()) { case 10: editText1.setTextSize(10); break; case 20: editText1.setTextSize(15); break; case 30: editText1.setTextSize(20); break; case 40: editText1.setTextSize(25); break; case 50: editText2.setTextSize(30); break; case 60: editText2.setTextSize(35); break; } return super.onContextItemSelected(item); } @Override public void onContextMenuClosed(Menu menu) { Toast.makeText(getApplicationContext(),"退出長按選單,",Toast.LENGTH_LONG).show(); super.onContextMenuClosed(menu); } } |
MainActivity.java
與使用 OptionMenu 不太一樣的地方是,在這裡我們是透過 onCreateContextMenu() 來定義長按選單的內容,並透過 onContextItemSelected() 來定義選單項選取時的觸發事件,最後透過 onContextMenuClosed() 來定義選單項關閉時的觸發事件。
@Override
public boolean onCreateContextMenu(Menu menu)
➥初始化選單內容。
@Override
public boolean onContextItemSelected(MenuItem item)
➥選單項選取時觸發處理,觸發時機與 OnMenuItemClickListener 監聽器類似。
@Override
public void onContextMenuClosed(Menu menu)
➥選單關閉時觸發處理。
延伸閱讀:
臉書留言
一般留言