一、常用方法
java onCreateOptionsMenu(Menu menu)
每次Activity一創建就會執行,一般只執行一次,創建並保留Menu的實例;
//獲取MenuInflater
MenuInflater inflater = getMenuInflater();
//加載Menu資源
inflater.inflate(R.menu.option_menu_normal,menu);
//此方法必須返回true,否則不予顯示
return true;
java onPrepareOptionsMenu(Menu menu)
每次menu被打開時,該方法就會執行一次,可用於對傳入的舊Menu對象進行修改操作;
java onOptionsItemSelected(MenuItem item)
每次menu菜單項被點擊時,該方法就會執行一次;
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.option_normal_1:
return true; //返回true,將結束點擊事件,不會進入下一級菜單
case R.id.option_normal_2:
return true;
case R.id.option_normal_3:
return true;
case R.id.option_normal_4:
return true;
default:
return super.onOptionsItemSelected(item); //不返回true,避免截斷菜單項的點擊事件
}
}
java invalidateOptionsMenu()
刷新menu里的選項里內容,它會調用onCreateOptionsMenu(Menu menu)方法
java onCreateContextMenu()
創建控件綁定的上下文菜單menu,根據方法里的View參數識別是哪個控件綁定
java onContextItemSelected(MenuItem item)
點擊控件綁定的上下菜單menu的內容項
java invalidateOptionsMenu()
通知系統刷新Menu,之后,onPrepareOptionsMenu會被調用
二、使用XML定義Menu
理論上而言,使用XML和Java代碼都可以創建Menu。但是在實際開發中,往往通過XML文件定義Menu,這樣做有以下幾個好處:
- 使用XML可以獲得更清晰的菜單結構
- 將菜單內容與應用的邏輯代碼分離
- 可以使用應用資源框架,為不同的平台版本、屏幕尺寸創建最合適的菜單(如對drawable、string等系統資源的使用)
要定義Menu,我們首先需要在res文件夾下新建menu文件夾,它將用於存儲與Menu相關的所有XML文件。
我們可以使用
、、三種XML元素定義Menu,下面簡單介紹一下它們:
- 是菜單項的容器。
- 元素必須是該文件的根節點,並且能夠包含一個或多個和元素。
- 是菜單項
- 用於定義MenuItem,可以嵌套元素,以便創建子菜單。
- 是元素的不可見容器(可選)。
- 可以使用它對菜單項進行分組,使一組菜單項共享可用性和可見性等屬性。
其中,是我們主要需要關注的元素,它的常見屬性如下:
android:id:菜單項(MenuItem)的唯一標識
android:icon:菜單項的圖標(可選)
android:title:菜單項的標題(必選)
android:showAsAction:指定菜單項的顯示方式。常用的有ifRoom、never、always、withText,多個屬性值之間可以使用|隔開
名稱 | 效果 |
---|---|
always | 菜單項永遠不會被收納到溢出菜單中,因此在菜單項過多的情況下可能超出菜單欄的顯示范圍。 |
ifRoom | 在空間足夠時,菜單項會顯示在菜單欄中,否則收納入溢出菜單中。 |
withText | 無論菜單項是否定義了icon屬性,都只會顯示它的標題,而不會顯示圖標。使用這種方式的菜單項默認會被收納入溢出菜單中。 |
never | 菜單項永遠只會出現在溢出菜單中。 |
- 在碎片中調用菜單時,要在
Fragment的onCreate()
方法中調用setHasOptionsMenu(true)
方法使之顯示出來。
三、三種菜單類型
1、選項菜單
選項菜單是一個應用的主菜單項,用於放置對應用產生全局影響的操作,如搜索/設置
包含多級子項的XML代碼,通過onOptionsItemSelected(MenuItem item)返回值為true來截斷
//包含多級子項的XML代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/option_sub_file" android:title="文件" app:showAsAction="ifRoom">
<menu>
<item android:id="@+id/file_new" android:title="新建"/>
<item android:id="@+id/file_save" android:title="保存"/>
<item android:id="@+id/file_more" android:title="更多">
<menu>
<item android:id="@+id/file_more_1" android:title="更多1"/>
<item android:id="@+id/file_more_2" android:title="更多2"/>
<item android:id="@+id/file_more_more" android:title="更多更多">
<menu>
<item android:id="@+id/file_more_more_1" android:title="更多更多1"/>
<item android:id="@+id/file_more_more_2" android:title="更多更多2"/>
</menu>
</item>
</menu>
</item>
</menu>
</item>
</menu>
//Java代碼
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.option_menu_normal,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.option_normal_1:
return true;
case R.id.option_normal_2:
return true;
case R.id.option_normal_3:
return true;
case R.id.option_normal_4:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
2、上下文菜單
- 上下文菜單是用戶長按某一元素時出現的浮動菜單。它提供的操作將影響所選內容,主要應用於列表中的每一項元素(如長按列表項彈出刪除對話框)。上下文操作模式將在屏幕頂部欄(菜單欄)顯示影響所選內容的操作選項,並允許用戶選擇多項,一般用於對列表類型的數據進行批量操作。
- 要提供浮動上下文菜單,可以參照以下步驟:
- 在Activity或Fragment中調用
registerForContextMenu(View v)
方法,注冊需要和上下文菜單關聯的View。如果將ListView或GridView作為參數傳入,那么每個列表項將會有相同的浮動上下文菜單。 - 在Activity或Fragment中重寫
onCreateContextMenu
方法,加載Menu資源。 - 在Activity或Fragment中重寫
onContextItemSelected
方法,實現菜單項的點擊邏輯。
- 在Activity或Fragment中調用
3、彈出菜單(不需要onCreateOptionsMenu方法)
- 彈出菜單以垂直列表形式顯示一系列操作選項,一般由某一控件觸發,彈出菜單將顯示在對應控件的上方或下方。它適用於提供與特定內容相關的大量操作。
- 可以將彈出菜單的使用拆分為以下四個步驟:
- 實例化PopupMenu,它的構造方法需要兩個參數,分別為Context以及PopupMenu依賴的View對象。
- 使用MenuInflater將Menu資源加載到
PopupMenu.getMenu()
返回的Menu對象中。 - 調用
setOnMenuItemClickListener
方法為PopupMenu設置點擊監聽器。 - 調用
PopupMenu.show()
將彈出菜單顯示出來。
//XML文件代碼
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/popup_add" android:title="添加"/>
<item android:id="@+id/popup_delete" android:title="刪除"/>
<item android:id="@+id/popup_more" android:title="更多"/>
</menu>
//Java文件代碼
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_popup_menu);
findViewById(R.id.popup_menu_view).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PopupMenu popupMenu=new PopupMenu(PopupMenuActivity.this,view);//1.實例化PopupMenu
getMenuInflater().inflate(R.menu.popup_menu,popupMenu.getMenu());//2.加載Menu資源
//3.為彈出菜單設置點擊監聽
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.popup_add:
Toast.makeText(PopupMenuActivity.this,"添加",Toast.LENGTH_SHORT).show();
return true;
case R.id.popup_delete:
Toast.makeText(PopupMenuActivity.this,"刪除",Toast.LENGTH_SHORT).show();
return true;
case R.id.popup_more:
Toast.makeText(PopupMenuActivity.this,"更多",Toast.LENGTH_SHORT).show();
return true;
default:
return false;
}
}
});
popupMenu.show();//4.顯示彈出菜單
}
});
}
另外參考大佬:https://blog.csdn.net/wangmx1993328/article/details/82781469