摘要:一直覺得菜單很簡單,但是瞧了瞧API文檔,才發現菜單還有這麼多東西,所以必須得整理一下各個菜單的使用方式,文章主要寫菜單的動態添加和通過XML添加,講解不同類型菜單的特點和使用方法。
============================================
文章結構:
1. 爲什麼會有菜單
2. 菜單的不同創建方法
2.1 動態創建
2.2 通過XML資源文件創建
3.菜單的類型(講了五種菜單的使用方法)
4.總結
============================================
1. 爲什麼會有菜單
菜單一般是提供一些設置或是軟件信息什麼的,移動設備的屏幕不像PC那麼大,不可能在屏幕搞一些按鍵來觸發一些平時使用不會經常操作的事件,比如設置軟件配置,查看軟件信息什麼的。這些功能可以添加到菜單選項中,既提供了該功能,又不會佔用屏幕空間。(純屬扯淡有木有啊!!!因爲我實在想不出要以什麼開頭寫這篇總結)
2. 菜單的不同創建方法
2.1 動態創建
通過重寫Activity中的onCreateOptionMenu方法來創建菜單,一般使用menu.add(“選項名”)爲添加一個菜單選項,menu.getItem(int itemIndex)則是根據選項的索引獲取該菜單選項,並對其進行操作,比如添加點擊事件onMenuItemClickListener,用addSubMenu添加子菜單等。
優點:創建方便,不需要建立資源文件。
缺點:對於菜單條目過多或多級菜單操作不方便,按鍵多添加點擊事件不方便。
2.2 通過XML資源文件創建
可以通過menu文件夾下的menu.xml創建菜單的樣式,然後再利用getMenuInflater().inflate(menuRes, menu)將創建的菜單樣式inflate到程序中。大體主要分三步:
第一步:建立XML資源文件:menu.xml文件一般的定義方式見如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <? xml version = "1.0" encoding = "utf-8" ?>
< item android:id = "@+id/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 > |
第二步:在onCreateOptionMenu回調函數完成XML資源的infate,把菜單資源文件壓入到程序中,不同菜單使用不同的回調函數,比如ContextMenu使用onCreateContextMenu:
1 2 3 4 5 | public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true ;
} |
第三步:如果我們需要給菜單添加點擊事件,一般我們是通過重寫onMenuItemSelected來設置的,不同菜單使用不同的點擊回調函數,比如ContextMenu使用onContextItemSelected寫法如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public boolean onMenuItemSelected( int featureId, MenuItem item) {
switch (item.getItemId()) {
case Item.ID1:
//do something
break ;
case Item.ID2:
//do something
break ;
//......
}
return super .onMenuItemSelected(featureId, item);
} |
3. 菜單的類型:
3.1 普通菜單:
一般的普通菜單,點擊菜單鍵後顯示出來的菜單,使用方法如第二點所述,只是設置item標籤時把showAsAction值設爲never即可。
3.2 顯示在ActionBar的菜單:
這樣的菜單可以直接從屏幕中看到,不需要點擊菜單鍵纔會顯示,要做到這個只需要把Item的showAsAction從never改成ifRoom(如果有空間則顯示)或always(總是顯示)。例子如下;
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 |
< item
android:id = "@+id/info"
android:orderInCategory = "100"
android:showAsAction = "never"
android:title = "軟件信息" >
< menu >
< item android:id = "@+id/authorInfo"
android:title = "軟件開發者信息" />
< item android:id = "@+id/versionInfo"
android:title = "軟件版本信息" />
</ menu >
</ item >
<!-- 建立一個在Action的菜單選項 -->
< item
android:id = "@+id/settings"
android:orderInCategory = "100"
android:showAsAction = "always"
android:icon = "@drawable/ic_launcher" >
< menu >
< item android:id = "@+id/sysSetting"
android:title = "系統設置" />
< item android:id = "@+id/softSetting"
android:title = "軟件設置" />
</ menu >
</ item >
</ menu > |
效果圖:
3.3 浮動菜單(屬於ContextMenu):
一般添加到ListView或GridView的菜單,長按菜單的某一項可以出發浮動菜單,定義這種菜單主要步驟如下:
1、建立一個View,常用的爲ListView或GridView;
2、建立XML菜單資源文件;
3、在Activity中的onCreateContextMenu函數中使用getMenuInflater().inflate()方法將XML菜單資源文件壓入;
4、在onContextItemSelected回調函數中添加菜單選項的點擊事件。
5、使用registerForContextMenu(View)爲該View註冊ContextMenu;
源碼示例如下:
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 | private ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] listItem = { "1" , "2" , "3" , "4" , "5" };
ArrayAdapter<String> aa = new ArrayAdapter<String>( this ,
android.R.layout.simple_list_item_1, listItem);
list = (ListView) findViewById(R.id.list);
list.setAdapter(aa);
registerForContextMenu(list);
//爲list註冊上下文菜單,通過onCreateContextMenu把XML菜單資源文件壓進來,
//通過onContextItemSelectd爲每個菜單選項添加長按點擊事件。
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super .onCreateContextMenu(menu, v, menuInfo);
getMenuInflater().inflate(R.menu.float_menu, menu);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) { //判斷長按點擊了那個選項,爲每個選項添加長按點擊事件
case R.id.exit:
showToast( "exit" );
break ;
case R.id.next:
showToast( "next" );
break ;
case R.id.back:
showToast( "back" );
break ;
}
return super .onContextItemSelected(item);
}
private void showToast(String str) {
Toast.makeText(MainActivity. this , str, Toast.LENGTH_SHORT).show();
} |
效果圖:
3.4 ActionMode菜單(也屬於ContextMenu):
顯示在ActionBar的菜單,這種菜單是用於定義比較重要或常用的功能,放在ActionBar比較顯眼。觸發這種菜單跟浮動菜單一樣,要長按,浮動菜單直接採用註冊方法,而該菜單則需要我們去設置View的長按事件(setOnLongClickListener)。
使用方法:
1、建立XML菜單資源文件;
2、建立一個內部類實現ActionMode.Callback接口,實現該接口的四個函數(onCreateActionMode,onPrepareActionMode,onActionItemClicked,onDestroyActionMode)
3、在onCreateActionMode把XML文件壓進來,而且返回true!
4、在onActionItemClicked中添加菜單選項點擊事件;
5、建立一個View,以Button爲例,添加OnLongClickListener事件,事件內容爲startActionMode(實現Callback接口的類);
源代碼示例:
(1)XML資源文件:
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 |
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:paddingBottom = "@dimen/activity_vertical_margin"
android:paddingLeft = "@dimen/activity_horizontal_margin"
android:paddingRight = "@dimen/activity_horizontal_margin"
android:paddingTop = "@dimen/activity_vertical_margin"
android:orientation = "vertical"
tools:context = ".MenuActivity2" >
< Button
android:id = "@+id/btn_actionMode"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "打開ActionMode菜單" />
< Button
android:id = "@+id/btn_popUp"
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:text = "打開PopUp菜單" />
</ LinearLayout > |
(2)實現Callback的Java代碼:
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 | private class callback implements ActionMode.Callback {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.user_info:
Toast.makeText(MenuActivity2. this , "You click user_info" ,
Toast.LENGTH_SHORT).show();
return true ;
case R.id.user_setting:
Toast.makeText(MenuActivity2. this , "You click user_setting" ,
Toast.LENGTH_SHORT).show();
return true ;
case R.id.user_login:
Toast.makeText(MenuActivity2. this , "You click user_login" ,
Toast.LENGTH_SHORT).show();
return true ;
default :
return false ;
}
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
getMenuInflater().inflate(R.menu.menu_activity2, menu);
return true ;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
Log.i( "cth" , "ActionMode is destroyed." );
actionMode = null ;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false ;
}
} |
(3)長按事件Java代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | btn_actionMode = (Button) findViewById(R.id.btn_actionMode);
btn_actionMode.setOnLongClickListener( new OnLongClickListener() { //添加長按事件
@Override
public boolean onLongClick(View v) {
if (actionMode != null ) {
return false ;
}
actionMode = startActionMode( new callback()); //開啓ActionMode菜單
v.setSelected( true ); //設置爲可選
return true ;
}
}); |
效果圖(紅框即爲ActionMode菜單):
3.5 Popup彈出菜單:
該類菜單需要和某個View綁定,當點擊該View時在該View的上面或下面(視屏幕空間而定)彈出菜單。
使用方法:
1、建立XML菜單資源文件;
2~5步均可在綁定View的點擊事件中實現!
2、建立PopupMenu對象,實例化傳入上下文context和綁定的View;
3、使用PopupMenu對象的getMenuInflater().inflate()把XML菜單文件壓進來,
4、使用PopupMenu對象自身的setOnMenuItemClickListener設置點擊事件;
5、使用PopupMenu對象自身的show顯示彈出菜單。
源代碼示例:
(1)在View的點擊事件中設置2~5步內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | btn_popUp = (Button) findViewById(R.id.btn_popUp);
btn_popUp.setOnClickListener( new OnClickListener() {
@TargetApi (Build.VERSION_CODES.HONEYCOMB)
@SuppressLint ( "NewApi" )
@Override
public void onClick(View v) {
PopupMenu popup = new PopupMenu(MenuActivity2. this , v); //建立PopupMenu對象
popup.getMenuInflater().inflate(R.menu.menu_activity2, //壓入XML資源文件
popup.getMenu());
popup.setOnMenuItemClickListener(MenuActivity2. this ); //設置點擊菜單選項事件
popup.show(); //顯示菜單
}
}); |
(2)點擊事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.user_info:
Toast.makeText(MenuActivity2. this , "You click user_info" ,
Toast.LENGTH_SHORT).show();
return true ;
case R.id.user_setting:
Toast.makeText(MenuActivity2. this , "You click user_setting" ,
Toast.LENGTH_SHORT).show();
return true ;
case R.id.user_login:
Toast.makeText(MenuActivity2. this , "You click user_login" ,
Toast.LENGTH_SHORT).show();
return true ;
default :
return false ;
}
} |
效果圖:
4. 總結:
菜單主要分兩種,OptionMenu和ContextMenu,只有浮動菜單(floating menu)和ActionMode菜單爲ContextMenu。OptionMenu建立菜單的方法爲在onCreateOptionMenu中inflate XML文件,在onMenuItemClick中設置點擊事件(PopupMenu使用自身的setOnMenuItemClickListener設置),ContextMenu建立菜單的方法爲在onCreateContextMenu中inflate XML文件(ActionMode在Callback中),在onContextItemClick中設置點擊事件。