//==================
快捷鍵:設置了快捷鍵后,在選項菜單已經彈出的情況下,可以通過按快捷鍵的方式直接選擇需要的菜單項。下面的3個方法都可以設定快捷鍵:
1)設置數字快捷鍵:setNumericShortcut(char numericChar)
2)設置數字和字符快捷鍵:setShortcut(char numericChar,char alphaChar);
3)設置字符快捷鍵:setAlphabeticShortcut(char alphachar)
短標題:當標題太長有可能顯示不全時,可以用短標題代替,用MenuItem調用setTitleCondensed(CharSequence title)就可設置
在第一次初始化了選項菜單之后,我們我們需要動態更改選項菜單的話,則需要重新實現onPrepareOptionMenu()回調方法,他會在每次顯示選項菜單之前調用。你可以在此回調方法里根據程序運行的情況即時地更新菜單項的內容,如標題、是否可用等。
//=======================================
1,菜單的基本用法:
1.1 OptionsMenu 選項菜單(按Menu鍵彈出的菜單)
Activity的onCreateOptionsMenu事件方法創建選項菜單
通過menu.add添加選項菜單項,返回一個MenuItem。
public MenuItem add(int groupId,int itemId,int order,CharSequence title);
如果groupId、itemId、order省略,默認都是0,顯示順序按添加順序顯示。
1.2 帶圖像的選項菜單
通過add方法返回的MenuItem的方法setIcon()設置圖片
1.3 管理Activity
MenuItem的setItent()方法
注意:如果設置了菜單項的單擊事件,並且單擊事件返回true,則setIntent方法失效。
1.4 響應菜單的單擊動作
通過調用MenuItem的setOnMenuItemClickListener方法可以設置菜單項的單擊事件。
還可以使用Activity類的onOptionsItemSelected和onMenuItemSelected方法來響應菜單項的單擊事件。這兩個方法都有一個MenuItem參數,可以使用其getTitle和getItemId方法來判斷單擊的是哪個菜單項。
既 然有3種方法響應菜單項單擊事件的方法,就會產生一個問題?如果同時使用這3種方法,他們都會起作用嗎?如果都起作用那調用順序又是如何呢?實際上,當 onMenuItemClick方法返回true時,另兩種單擊事件的響應方式都會失效;如果沒有設置onMenuItemClickListener, 系統會根據在onMenuItemSelected方法中調用父類的onMenuItemSelected方法的位置來決定先調用 onOptionsItemSelected方法還是先調用onMenuItemSelected方法。
也就是說super.onMenuItemSelected(featureId,item);調用了onOptionsItemSelected方法
1.5 動態添加、修改和刪除選項菜單
實現這個功能的關鍵是獲得描述選項菜單的Menu對象。
Activity類中的很多方法都可以獲得Menu對象。例如,onCreateOptionsMenu方法的menu參數,我們要做的就是在onCreateOptionMenu方法中將Menu對象保存在類變量中。
1.6 帶復選框和選項按鈕的子菜單
Menu.addSubMenu方法用來添加子菜單。該方法有4種重載形式:
SubMenu addSubMenu(final int gourpId,final int itemId,int order,final CharSequence title);
SubMenu是Menu的子接口,添加SubMenu后,可以通過SubMenu.add方法添加其子菜單項。在子菜單項上不能顯示圖像,但可以在子菜單的頭部顯示圖像,不過子菜單項可以帶復選框和選項按鈕。
例如:
SubMenu fileSubMenu=menu.addSubMenu(1,1,2,"文件"); //添加SubMenu
fileSubMenu.setIcon(R.drawable.file); //設置在選項菜單中顯示的圖像
fileSubMenu.setHeaderIcon(R.drawable.headerfile); //設置子菜單頭的圖像
MenuItem newMenuItem=fileSubMenu.add(1,2,2,"新建");
newMenuItem.setCheckable(true); //將第一個子菜單項設置成復選框類型
newMenuItem.setChecked(true); //選中第一個子菜單項中的復選框
MenuItem openMenuItem=fileSubMenu.add(2,3,3,"打開");
MenuItem exitMenuItem=fileSubMenu.add(2,4,4,"退出");
exitMenuItem.setChecked(true); //將第3個子菜單項的選項按鈕設置為選中狀態
fileSubMenu.setGroupCheckable(2,true,true);//將后兩個子菜單項設置成選項按鈕類型
在編寫上面代碼時應注意以下幾點:
1)添加子菜單並不是直接在MenuItem下添加菜單項,而需要使用addSubMenu方法創建一個SubMenu對象。
2) 將子菜單項設置成復選框類型,需要使用MenuItem.setCheckable方法。但設置成選項按鈕類型,不需要使用setCheckable方 法,而要將同一組的選項按鈕的groupI的設置成相同的值,同時使用setGroupCheckable方法來設置這個groupId。該方法的第1個 參數是指定子菜單項的groupId,第2個參數必須為true。如果第3個參數為true,相同groupId的子菜單項會被設置成選項按鈕效果;如果 為false,相同groupId的子菜單項會被設置成復選框效果。根據相同groupId設置的選項按鈕和復選框除了顯示效果,並沒有什么其他的不同。 其代表的含義完全由開發人員決定。
3)使用setChecked方法可以將復選框或選項按鈕設置成選中狀態。
4)選項菜單不支持嵌套子菜單。否則將拋出異常。
1.7 上下文菜單
上下文菜單有些和子菜單類似,也分為菜單頭和菜單項。
通過onCreateContextMenu方法創建上下文菜單。
可以使用ContextMenu.setHeaderTitle和ContextMenu.setHeaderIcon方法設置上下文菜單頭的標題和圖像。上下文菜單項也是不能顯示圖像,但可以帶復選框和選項按鈕。也不支持嵌套。
上下文菜單必須注冊到指定的View上才能顯示。注冊上下文菜單可以使用Activity.registerForContextMenu方法。
例如:registerForContextMenu(button);
上下文菜單項的單擊事件也可以使用單擊事件類和onMenuItemSelected方法來響應,還有覆蓋
Activity.onContextItemSelected方法
1.8 菜單事件
Activity類還有一些與菜單相關的事件方法,這些方法的定義如下:
public boolean onPrepareOptionsMenu(Menu menu);
public void onOptionsMenuClosed(Menu menu);
public void onContextMenuClosed(Menu menu);
public boolean onMenuOpened(int featureId,Menu menu);
這些方法的含義如下:
1)onPrepareOptionsMenu:在顯示選項菜單之前調用。一般用來修改即將顯示的選項菜單。
2)onOptionsMenuClosed:在關閉選項菜單時被調用。
3)onContextMenuClosed:在關閉上下文菜單時被調用。
4)onMenuOpened:在顯示選項菜單之前被調用。該方法在onPrepareOptionsMenu方法之后調用。
6.1.9 從菜單資源中裝載菜單
在res\menu目錄中的文件才菜單資源文件。
<menu xmlns:android="...">
<item ...
<item ..
</menu>
使用 getMenuInflater().inflate(R.menu.file_menu,menu); 加載
2 菜單特效
2.1 自定義菜單
系統提供的菜單看起來有些“土”,通過onKeyDown和PopupWindow實現自定義的菜單。
首先寫一個布局文件准備給PopupWindow使用。
然后監聽“menu”鍵和“back”鍵按下動作。
1)按下back鍵時,如果選項菜單已經彈出,則關閉選項菜單。
2)如果選項菜單未彈出,則執行super.onKeyDown
@Override
public boolean onKeyDown(int keyCode,KeyEvent event)
{
switch (keyCode)
{
case KeyEvent.KEYCODE_MENU: //如果按下“menu”鍵
if (state==1) //自定義的state表示狀態,1表示選項菜單已彈出
return false;
//裝載選項菜單布局文件
layout=getLayoutInflater().inflate(R.layout.menu_layout,null);
pop=new PopupWindow(layout,getWindowManager().getDefaultDisplay().getWidth(),getWindowManager().getDefaultDisplay().getHeight());
//設置彈出窗口的位置
pop.showAcLocation(layout,Gravity.BOTTOM,0,0);
View home=layout.findViewById(R.id.home);
home.seonClickListener(...);
...
pop.dismiss();
...
state=2;
return false;
case KeyEvent.KEYCODE_BACK:
if (state==1) ...
else ...
2.2 模擬UCWeb效果菜單
通過onCreateOptionsMenu和onMenuOpened兩個方法相互配合來彈出自定義菜單。
在顯示選項菜單之前,系統會調用onMenuOpened方法,如果該方法返回false,則不再顯示選項菜單。因此,可以在onMenuOpened方法中彈出用於顯示自定義菜單的窗口。
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
//必須構建一項,否則系統不會調用onMenuOpened方法
menu.add("menu");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onMenuOpened(int featureId,Menu menu)
{
if (popup!=null) {
if (popup.isShowing())
{
popup.dismiss();
}
else
{
View layout=getLayoutInflater().inflate(R.layout.main,null);
//popup.showAtLocation(layout,Gravity.CENTER,0,0);
}
return false;
}
2.3 QuickContactBadge與聯系人菜單
我們在使用Android內置的聯系人功能時發現,在單擊某個聯系人之后,會彈出一個可以選擇的圖像菜單,其中包括撥打電話、發短信等功能。
這 個功能實際上是由QuickContactBadge控件完成的。QuickContactBadge是ImageView的子類,因 此,QuickContactBadge完全可以作為一個ImageView來使用。但QuickContactBadge還可以查詢系統的聯系人列表, 並根據聯系人的相關信息顯示如圖6.12所示的快捷菜單。現在我們先在布局文件中放兩個QuickContactBadge控件。
<?xml version...>
<LinearLayout ...>
<QuickContactBadge ... android:src="http://supershll.blog.163.com/blog/@drawable/ic_contact_picture" style="?android:attr/quickContactbadgeStyleWindowSmall" />
<QuickContactBadge ... style="?android:attr/quickContactbadgeStyleWindowLarge" />
</LinearLayout>
style屬性指定了顯示圖像菜單的風格。如果quickContactBadgeStyleWindowLarge風格可以顯示聯系人的姓名,quickContactBadgeStyleWindowSmall風格只顯示圖像菜單。
部分示例代碼:
String select="(("+Contacts.DISPLAY_NAME+" NOTNULL) AND ("+Contacts.HAS_PHONE_NUMBER+"=1) AND ("+Contacts.DISPLAY_NAME+" !='' ))";
//查詢所有的聯系人
Cursor cursor=getContentResolver().query(Contacts.CONTENT_URI,CONTACTS_SUMMARY_PROJECTION,select,null,Contacts.DISPLAY_NAME+" COLLATE LOCALIZED ASC");
//將記錄指針移動到第一條記錄
cursor.moveToFirst();
//創建第一個QuickContactBadge對象
QuickContactBadge badge1=findViewById(R.id.badge1);
... badge2=...;
//獲得聯系人的ID
long contactId=cursor.getLong(cursor.getColumnIndex(Contacts._ID));
//獲得聯系人的Lookup_key
String lookupKey=cursor.getString(cursor.getColumnIndex(Contacts.LOOKUP_KEY));
//將聯系人與QuickContactBadge關聯
badge1.assignContactUri(Contacts.getLookupUri(contactId,lookupKey));
cursor.moveToNext();
contactId=....;
lookupKey=...
badge2.assignContactUri(...);
注意:QuickContactBadge控件並不會自動顯示聯系人的圖像,要想顯示圖像,需要像ImageView一樣設置src屬性、
擴展學習:除了使用QuickContactBadge.assignContactUri方法關聯聯系人外,還可以使用
QuickContactBadge.assignContactFromEmail(String emailAddress,boolean lazyLookup)關聯Email
QuickContactBadge.assignContactFromPhone(String phoneNumber,boolean lazyLookup) 關聯電話號碼
如 果lazyLookup為true,並不會立即通過Email或Phone查找聯系人,直接QuickContactBadge控件被單擊。如果有多個聯 系人使用了同一個電話或Email,則只顯示第一個查到的聯系人信息。使用這兩個方法與聯系人關聯,單擊QuickContactBadge控件並不會顯 示圖像菜單,而會直接跳到聯系人界面。