Android開發之Menu:OptionMenu(選項選單)、ContextMenu(上下文選單)、SubMenu(子選單)
選單的概念,現在已經很普及了。
Windows系統、Mac、桌面版Linux、Java Swing等,都有視覺化選單。
一、Android平臺3種選單
選項選單(OptionMenu)、上下文選單(ContextMenu)、子選單(SubMenu)。
1.Option Menu
一般手機上都會提供Menu的按鈕,對應的就是這個選單彈出。
主要步驟就是複寫Activity父類中的onCreateOptionMenu(Menu menu)方法,然後通過Menu的add方法來新增選單進去,
最後,當我們去點選某項的選項的時候,覆蓋重寫onOptionsItemSelected(MenuItem item)這個方法去實現點選事件 。
2.Context Menu
上下文選單,就是和當時的環境(使用者介面、某個流程)相關的選單。
比如對於檔案管理器來說,一些增刪改查就可以擺在ContextMenu中,它其實是實現了一個使用者長按點選後彈出的來一個選單。
3.SubMenu
子選單,在概念上,子選單可以說是“屬於”以上型別的。
二、理解Android選單
選單是許多應用程式不可或缺的一部分,Android中更是如此,所有搭載Android系統的手機甚至都要有一個"Menu"鍵,由此可見選單在Android程式中的特殊性。Android SDK提供的選單有如下幾種:
選項選單:最常規的選單,android中把它叫做option menu
子選單:android中點選子選單將彈出懸浮視窗顯示子選單項。子選單不支援巢狀,即子選單中不能再包括其他子選單。
上下文選單:android中長按檢視控制元件後出現的選單,windows點選右鍵彈出的選單即上下文選單
圖示選單:這個比較簡單,就是帶icon的選單項,需要注意的是子選單項、上下文選單項、擴充套件選單項均無法顯示圖示。
選擇選單(alternative menu):用的比較少,以後單獨介紹,本文先跳過(其實是我還沒弄明白啦o(≧v≦)o~~)
擴充套件選單:選項選單最多隻能顯示6個選單項,超過6個時,第6個選單項會被系統替換為一個叫“更多”的子選單,原來顯示不下的選單項都作為“更多”選單的子選單項。
Android SDK提供的選單有如下幾種:
選項選單:最常規的選單,android中把它叫做option menu
子選單:android中點選子選單將彈出懸浮視窗顯示子選單項。子選單不支援巢狀,即子選單中不能再包括其他子選單。
上下文選單:android中長按檢視控制元件後出現的選單,windows點選右鍵彈出的選單即上下文選單
圖示選單:這個比較簡單,就是帶icon的選單項,需要注意的是子選單項、上下文選單項、擴充套件選單項均無法顯示圖示。
選擇選單(alternative menu):用的比較少。(網上找了篇文章,沒有看懂,很陌生的感覺。)
擴充套件選單:選項選單最多隻能顯示6個選單項,超過6個時,第6個選單項會被系統替換為一個叫“更多”的子選單,原來顯示不下的選單項都作為“更多”選單的子選單項。
android.view.Menu介面代表一個選單,android用它來管理各種選單項。
注意我們一般不自己建立menu,因為每個Activity預設都自帶了一個,我們要做的是為它加選單項和響應選單項的點選事件。
android.view.MenuItem代表每個選單項,android.view.SubMenu代表子選單。其三者的關係可以用下圖來表示
每個activity包含一個選單,一個選單又能包含多個選單項和多個子選單,子選單其實也是選單(因為它實現了Menu介面),因此子選單也可以包含多個選單項。
SubMenu繼承了Menu的addSubMenu()方法,但呼叫時會丟擲執行時錯誤。
OnCreateOptionsMenu()和OnOptionsMenuSelected()是activity中提供了兩個回撥方法,用於建立選單項和響應選單項的點選。
三、響應OptionMenu的3種方式
1.重寫activity類的 onOptionsItemSelected(MenuItem)回撥方法,每當有選單項被點選時,android就會呼叫該方法,並傳入被點選選單項。
publicboolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//響應每個選單項(通過選單項的ID)
case1:
// do something here
break;
default:
//對沒有處理的事件,交給父類來處理
return super.onOptionsItemSelected(item);
}
//返回true表示處理完選單項的事件,不需要將該事件繼續傳播下去了
return true;
}
這個地方的“default”,我覺得比較好。
雖然第一種方法是推薦使用的方法,android還是提供了類似java swing的監聽器方式來響應選單。使用監聽器的方式分為兩步:
//第一步:建立監聽器類
class MyMenuItemClickListener implements OnMenuItemClickListener {
@Override
publicboolean onMenuItemClick(MenuItem item) {
// do something here...
returntrue; //finish handling
}
}
//第二步:為選單項註冊監聽器
menuItem.setOnMenuItemClickListener(new MyMenuItemClickListener());
3.使用Intent響應選單
第3種方式是直接在MenuItem上呼叫setIntent(Intent intent)方法,這樣android會自動在該選單被點選時呼叫 startActivity(Intent)。
但是個人認為與其這樣還不如直接在onOptionsItemSelected的case裡手動呼叫 startActivity(Intent)來的直觀。
個人比較傾向於第1種方式,如果選單事件程式碼比較多,可以考慮第2種方式。
第2種方式的問題是,可能需要傳遞引數到Listener。
四、圖示選單
// 子選單項不支援顯示圖示,這樣做是沒意義的,儘管不會報錯!
menuitem1.setIcon(R.drawable.displaysettings);
//但是子選單本身是支援圖示的
subMenu.setIcon(R.drawable.settings);
選單的前面可以有個圖示,後文的程式碼中,不再具體演示用法。
五、Context Menu
上下文選單與Options Menu最大的不同在於,Options Menu的擁有者是Activity,而上下文選單的擁有者是Activity中的View。
每個Activity有且只有一個Options Menu,它為整個Activity服務。
而一個Activity往往有多個View,並不是每個View都有上下文選單,這就需要我們顯示地通過registerForContextMenu(View view)來指定。
儘管上下文選單的擁有者是View,生成上下文選單卻是通過Activity中的onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)方法,
該方法很像生成Options Menu的onCreateOptionsMenu(Menu menu)方法。
兩者的不同在於,onCreateOptionsMenu只在使用者第一次按“Menu”鍵時被呼叫,而onCreateContextMenu會在使用者每一次長按View時被呼叫,而且View必須已經註冊了上下文選單。
另一個值得注意的就是上圖中的ContextMenuInfo,該類的物件被傳入onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)方法,那麼它有什麼用呢?
有時候,檢視元素需要向上下文選單傳遞一些資訊,比如該View對應DB記錄的ID等,這就要使用ContextMenuInfo。
需要傳遞額外資訊的View需要重寫getContextMenuInfo()方法,返回一個帶有資料的ContextMenuInfo實現類物件。
如何建立和響應上下文選單的3個步驟
1.在activity的onCreate(...)方法中為一個view註冊上下文選單。
2.在onCreateContextMenuInfo(...)中生成上下文選單。
3.在onContextItemSelected(...)中響應上下文選單項。
六、程式碼示例
需要說明的是,Option Menu,按左鍵選單或者右鍵選單按鈕,彈出選單。
Context Menu,長按View,彈出選單。
OptionMenu程式碼
package cn.fansunion.menu;
import cn.fansunion.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.Toast;
/**
* ①:直接去覆蓋public boolean onCreateOptionsMenu(Menu menu) { code......},
* 這個方法,需要注意的是,這個方法如果覆蓋的了,只會被建立一次,也就是說, 選項選單隻會去被例項化一次,之後就不會被去呼叫了
* ②:呼叫Menu中的add()方法,來新增每一個選單選項, add(groupId, itemId, order, titleRes) group:
* 選項組號,一般都設定成0就OK啦 itenId: 選項的Id 很重要 order:順序,一般來說都設定0就行了 titelRes: 選項的標題名字
* ③:當我們去點選某項的選項的時候,覆蓋重寫onOptionsItemSelected(MenuItem item)這個方法去實現點選事件.
*/
public class OptionMenuActivity extends Activity {
// 點選選單選項的常量Id
private static final int MENU_ONE = 1;
private static final int MENU_TWO = 2;
private static final int MENU_THREE = 3;
private int MENU_SUB = 11;
private static final int GROUP_ZERO = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.option_menu);
}
/**
* @param group
* : 選項組號,一般都設定成0就OK啦
* @param itenId
* : 選項的Id 很重要
* @param order
* :順序,一般來說都設定0就行了
* @param titelRes
* : 選項的標題名字
*/
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(GROUP_ZERO, MENU_ONE, GROUP_ZERO, "小雷");
// 一個menu可以包括多個子選單
SubMenu subMenu=menu.addSubMenu(GROUP_ZERO, MENU_SUB, GROUP_ZERO, "小雷興趣");
subMenu.add(GROUP_ZERO, MENU_TWO, GROUP_ZERO, "網際網路技術");
subMenu.add(GROUP_ZERO, MENU_THREE, GROUP_ZERO, "投資理財");
return true;
}
/**
*
* @param item
* .getItemId() 獲取被點選的Id
*/
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ONE:
Toast.makeText(this, "你點選了Menu1", Toast.LENGTH_LONG).show();
break;
case MENU_TWO:
Toast.makeText(this, "你點選了Menu2", Toast.LENGTH_LONG).show();
break;
case MENU_THREE:
Toast.makeText(this, "你點選了Menu3", Toast.LENGTH_LONG).show();
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
}
佈局檔案layout
option_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="FansUnion,Android Demo "/>
</LinearLayout>
ContextMenu程式碼
package cn.fansunion.menu;
import cn.fansunion.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class ContextMenuActivity extends Activity {
private static final int GROUP = 0;
private static final int MENU_ONE = 1;
private static final int MENU_TWO = 2;
private static final int MENU_THREE = 3;
private TextView contextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.context_menu);
contextView = (TextView) this.findViewById(R.id.contextMenu);
registerForContextMenu(contextView);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(GROUP, MENU_ONE, 0, "小雷FansUnion");
menu.add(GROUP, MENU_TWO, 0, "網際網路技術");
menu.add(GROUP, MENU_THREE, 0, "投資理財");
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ONE:
Toast.makeText(this, "你 點選的是Menu1", Toast.LENGTH_LONG).show();
contextView.setText("你點選的是Menu1");
break;
case MENU_TWO:
Toast.makeText(this, "你點選的是Menu2", Toast.LENGTH_LONG).show();
contextView.setText("你點選的是Menu2");
break;
case MENU_THREE:
Toast.makeText(this, "你點選的是Menu3", Toast.LENGTH_LONG).show();
contextView.setText("你點選的是Menu3");
break;
}
return true;
}
}
佈局layout
context_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/contextMenu"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="FansUnion,ContextMenuDemo "/>
</LinearLayout>
注:本文主要是根據以下3個地方的參考資料,簡化和優化了文字和程式碼,改造而來的。
參考資料
http://www.cnblogs.com/codingmyworld/archive/2011/08/21/2147829.html(5篇很不錯,最佳參考資料)
http://nullpointsun.iteye.com/blog/1589850(中規中矩,1篇長的)
http://www.linuxidc.com/Linux/2011-12/49593.htm(馬馬虎虎,3篇短的)
相關文章
- Tkinter (13) 選項選單部件 OptionMenu
- Android 選單(OptionMenu)大全 建立你自己的選單Android
- c# winform之contextmenu快捷選單C#ORMContext
- Tkinter (10) 選單部件 Menu
- vue元件之路之menu導航選單Vue元件
- 【Android】Menu不同選單的使用介紹Android
- jQuery 關於點選選單項,使子條目jQuery
- ABP後臺管理頁面AdminLTE框架,實現選單項點選後,選單展開當前選單項高亮框架
- 選中select下拉選單項提交表單
- JavaGUI——swing元件基礎(八)選單欄/選單/子選單元件JMenuBar/JMenu/JMenuItemJavaGUI元件
- 建立上下文選單
- win10開始選單怎麼增加休眠選項?win10開始選單增加休眠選項的辦法Win10
- 【iOS】今日頭條選單選項篇iOS
- c# winform之選單menu_menuitem_mainmenu_etcC#ORMUIAI
- handsontable如何重寫右鍵選單(contextmenu)Context
- jQuery右鍵選單外掛jQuery ContextMenujQueryContext
- PyQt5 之勾選選單QT
- 使用點陣圖選單項——點陣圖選單項例項 (轉)
- tkinter中menu選單控制元件(十二)控制元件
- Android開發之TabLayout實現頂部選單AndroidTabLayout
- 圓形可滑動選單(可以動態新增選單項)
- 單選多選按鈕
- [開發教程] 第32講:Bootstrap導航選單裡的下拉選單boot
- 【前端積累】二級選單,滑鼠滑過的時候子選單顯示,當滑鼠離開的時候子選單隱藏...前端
- Windows開始選單欄軟體:DoYourData Start Menu for MacWindowsMac
- Win8.1開始選單Start Menu X體驗
- Oracle HRMS選單中“禁用多個視窗”選單項的作用?Oracle
- JCEF 如何修改右鍵選單項(JCEF在右鍵選單中新增開發者選項-show dev tools)dev
- android(一) 選單建立Android
- BootstrapBlazor實戰 Menu 導航選單使用(1)bootBlazor
- BootstrapBlazor實戰 Menu 導航選單使用(2)bootBlazor
- 選擇下拉選單項實現跳轉效果
- 對 Xcode 選單選項的詳細探索XCode
- 精簡選單和完整選單之間進行切換
- Android列表實現單選、多選、全選、取消、刪除Android
- 下拉選單
- 選單(轉)
- 選中select下拉選單第一項不觸發事件事件